Skip to content

Commit

Permalink
Port Simple Components Including Bulma
Browse files Browse the repository at this point in the history
Ported components (stories) into `src/component-library`. These
components are called *simple* because they use Bulma CSS (and related
dependencies) but do not rely on other components. In addition, if a
component requires the handling of images, it is omitted in this commit.

Added Components:

* Checkbox (requires `bulma-checkradio`)
* Dropdown
* Form
* Input
* Modal
* ProgressBar
* Steps (requires `bulma-steps`)
* Table
* Tabs
* ToggleSwitch (requires `bulma-switch`)
  • Loading branch information
ThePhisch committed Feb 16, 2023
1 parent e171d26 commit 35f4ef9
Show file tree
Hide file tree
Showing 32 changed files with 887 additions and 0 deletions.
50 changes: 50 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Expand Up @@ -16,6 +16,10 @@
"@primer/css": "^20.8.2",
"@types/react": "18.0.27",
"@types/react-dom": "18.0.10",
"bulma": "^0.9.4",
"bulma-checkradio": "^2.1.3",
"bulma-steps": "^2.2.1",
"bulma-switch": "^2.0.4",
"eslint": "8.33.0",
"eslint-config-next": "13.1.6",
"inversify": "^6.0.1",
Expand Down
26 changes: 26 additions & 0 deletions src/component-library/Checkbox/Checkbox.stories.tsx
@@ -0,0 +1,26 @@
import { ComponentMeta, ComponentStory } from '@storybook/react'
import { Checkbox } from './Checkbox'

export default {
title: 'Components/Button',
component: Checkbox,
} as ComponentMeta<typeof Checkbox>

const Template: ComponentStory<typeof Checkbox> = args => <Checkbox {...args} />

export const CheckBox = Template.bind({})
CheckBox.args = {
label: 'example',
kind: 'success',
isChecked: true,
style: 'rounded_checkbox',
}

export const RadioButton = Template.bind({})
RadioButton.args = {
label: 'example',
kind: 'info',
style: 'background-color',
isChecked: true,
type: 'radio',
}
33 changes: 33 additions & 0 deletions src/component-library/Checkbox/Checkbox.tsx
@@ -0,0 +1,33 @@
import './checkbox.scss'

import { useState } from 'react'

export const Checkbox = ({
label = '',
type = 'checkbox',
size,
kind,
style,
isChecked = false,
name,
handleChange,
}: CheckboxProps) => {
const [checked, setChecked] = useState(isChecked)
return (
<div
onClick={(event: any) => {
setChecked(!checked)
handleChange?.(event)
}}
>
<input
className={`rucio-checkradio ${type} ${size} ${kind} ${style}`}
type={type}
checked={checked}
onChange={args => args}
name={name}
/>
<label>{label}</label>
</div>
)
}
40 changes: 40 additions & 0 deletions src/component-library/Checkbox/checkbox.scss
@@ -0,0 +1,40 @@
@import 'bulma/sass/elements/_all.sass';
@import 'bulma/sass/form/_all.sass';
@import 'bulma-checkradio/src/sass/index.sass';

.rucio-checkradio {
@extend .is-checkradio;
&.success {
@extend .is-success;
}
&.warning {
@extend .is-warning;
}
&.danger {
@extend .is-danger;
}
&.info {
@extend .is-info;
}
&.small {
@extend .is-small;
}
&.medium {
@extend .is-medium;
}
&.large {
@extend .is-large;
}
&.rounded_checkbox {
@extend .is-circle;
}
&.block {
@extend .is-block;
}
&.no_border {
@extend .has-no-border;
}
&.background-color {
@extend .has-background-color;
}
}
16 changes: 16 additions & 0 deletions src/component-library/Dropdown/Dropdown.stories.tsx
@@ -0,0 +1,16 @@
import { ComponentMeta, ComponentStory } from '@storybook/react'

import { Dropdown } from './Dropdown'

export default {
title: 'Components/Dropdown',
component: Dropdown,
} as ComponentMeta<typeof Dropdown>

const Template: ComponentStory<typeof Dropdown> = args => <Dropdown {...args} />

export const Primary = Template.bind({})
Primary.args = {
label: 'Dropdown',
options: ['option 1', 'option 2', 'option 3'],
}
53 changes: 53 additions & 0 deletions src/component-library/Dropdown/Dropdown.tsx
@@ -0,0 +1,53 @@
import './dropdown.scss'

import { useState } from 'react'

export const Dropdown = ({
label = '',
options = [],
...props
}: DropdownProps) => {
const [isActive, setActive] = useState(false)
const [selectedlabel, setSelectedLabel] = useState(label)
return (
<div className={isActive ? 'rucio-dropdown active' : 'rucio-dropdown'}>
<div className="dropdown-trigger">
<button
className="button"
aria-haspopup="true"
aria-controls="dropdown-menu"
onClick={() => {
setActive(!isActive)
}}
>
<span>{selectedlabel}</span>
<span className="icon is-small">
<p>&#9660;</p>
</span>
</button>
</div>
<div
className="dropdown-menu"
id="dropdown-menu"
role="menu"
onClick={(event: any) => {
setActive(false)
setSelectedLabel(event?.target?.value)
props?.handleChange?.(event)
}}
>
<div className="dropdown-content">
{options.map((element: any, index: number) => (
<option
className={'dropdown-item'}
value={element}
key={index}
>
{element}
</option>
))}
</div>
</div>
</div>
)
}
19 changes: 19 additions & 0 deletions src/component-library/Dropdown/dropdown.scss
@@ -0,0 +1,19 @@
@import 'bulma/sass/components/dropdown.sass';

.rucio-dropdown {
@extend .dropdown;
cursor: pointer;
margin: auto 2px;
border: 1px solid gray;
border-radius: 5px;
&.active {
@extend .is-active;
}
}
option {
text-align: left;
}

option:hover {
background-color: #f5f5f5ff;
}
15 changes: 15 additions & 0 deletions src/component-library/Form/Form.stories.tsx
@@ -0,0 +1,15 @@
import { ComponentStory, ComponentMeta } from '@storybook/react'

import { Form } from './Form'

export default {
title: 'Components/Form',
component: Form,
} as ComponentMeta<typeof Form>

const Template: ComponentStory<typeof Form> = args => <Form {...args} />

export const Primary = Template.bind({})
Primary.args = {
title: 'Form',
}
61 changes: 61 additions & 0 deletions src/component-library/Form/Form.tsx
@@ -0,0 +1,61 @@
import './form.scss'

import { useEffect } from 'react'

import { Button } from '../Button/Button'

export const Form = ({
title = 'Title',
subtitle = 'Subtitle',
children = (
<div>
<div className="field">
<div className="control">
<input className="input" type="text" placeholder="Input" />
</div>
</div>

<div className="field">
<p className="control">
<span className="select">
<select>
<option>Select dropdown</option>
</select>
</span>
</p>
</div>

<div className="buttons">
<Button
label="Submit"
size="medium"
type="submit"
kind="primary"
/>
</div>
</div>
),
onSubmit = () => {
alert('form submitted')
},
}: FormProps) => {
useEffect(() => {
const formElements: any = document.getElementsByClassName('rucio-form')
Array.from(formElements).forEach((formElement: any) => {
formElement.onkeydown = () => {
const keyboardEvent = window?.event as KeyboardEvent
if (keyboardEvent?.key === 'Enter') {
onSubmit(keyboardEvent)
}
}
})
})

return (
<form className="rucio-form" onSubmit={onSubmit}>
<h1 className="title">{title}</h1>
<p className="subtitle">{subtitle}</p>
{children}
</form>
)
}
18 changes: 18 additions & 0 deletions src/component-library/Form/form.scss
@@ -0,0 +1,18 @@
@import 'bulma/sass/utilities/_all.sass';
@import 'bulma/sass/elements/_all.sass';
@import 'bulma/sass/form/_all.sass';

.rucio-form {
.header {
@extend .title;
}
.subheader {
@extend .subtitle;
}
.entry {
@extend .field;
.controls {
@extend .control;
}
}
}
27 changes: 27 additions & 0 deletions src/component-library/Input/Input.stories.tsx
@@ -0,0 +1,27 @@
import { ComponentStory, ComponentMeta } from '@storybook/react'

import { Input } from './Input'

export default {
title: 'Components/Input',
component: Input,
} as ComponentMeta<typeof Input>

const Template: ComponentStory<typeof Input> = args => <Input {...args} />

export const TextInput = Template.bind({})
TextInput.args = {
size: 'medium',
kind: 'primary',
label: 'TextInput',
}

export const NumberInput = Template.bind({})
NumberInput.args = {
type: 'number',
show: 'rounded',
kind: 'primary',
label: 'NumberInput',
min: 0,
max: 5,
}

0 comments on commit 35f4ef9

Please sign in to comment.