Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.0] - 2024-03-10
* [FuiCheckbox] - Fixed naming ([#8](https://github.com/functional-ui/functional-ui-kit/issues/8))
* [FuiTextInput / FuiRadio / FuiStepper] - Improved adherence to WCAG ([#7](https://github.com/functional-ui/functional-ui-kit/issues/7))
* [Docs] - Upgrade to Storybook@7.6.17

## [0.1.0] - 2024-02-07
* [FuiPopover] - Removed `react-tiny-popover` and replace with `floating-ui`
* [FuiOptionGroup] - New Component 🎉
Expand Down
29 changes: 17 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"name": "functional-ui-kit",
"version": "0.1.0",
"version": "1.0.0",
"description": "Functional UI Kit",
"homepage": "https://functional-ui-kit.com/",
"scripts": {
"build": "vite build --config vite.config.ts",
"dev": "npm run storybook",
Expand Down Expand Up @@ -33,6 +34,10 @@
"style"
],
"author": "Alex Yakir",
"repository": {
"type": "git",
"url": "https://github.com/functional-ui/functional-ui-kit.git"
},
"license": "ISC",
"dependencies": {
"@floating-ui/react": "^0.25.2",
Expand All @@ -44,17 +49,17 @@
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.5",
"@storybook/addon-designs": "^7.0.7",
"@storybook/addon-essentials": "^7.6.10",
"@storybook/addon-interactions": "^7.6.10",
"@storybook/addon-links": "^7.6.10",
"@storybook/addon-mdx-gfm": "^7.6.10",
"@storybook/addon-toolbars": "^7.6.10",
"@storybook/blocks": "^7.6.10",
"@storybook/manager-api": "^7.6.10",
"@storybook/react": "^7.6.10",
"@storybook/react-webpack5": "^7.6.10",
"@storybook/addon-essentials": "^7.6.17",
"@storybook/addon-interactions": "^7.6.17",
"@storybook/addon-links": "^7.6.17",
"@storybook/addon-mdx-gfm": "^7.6.17",
"@storybook/addon-toolbars": "^7.6.17",
"@storybook/blocks": "^7.6.17",
"@storybook/manager-api": "^7.6.17",
"@storybook/react": "^7.6.17",
"@storybook/react-webpack5": "^7.6.17",
"@storybook/testing-library": "^0.2.2",
"@storybook/theming": "^7.6.10",
"@storybook/theming": "^7.6.17",
"@types/react": "^18.0.0",
"@types/react-modal": "^3.16.0",
"@typescript-eslint/eslint-plugin": "^5.59.5",
Expand All @@ -71,7 +76,7 @@
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"storybook": "^7.6.10",
"storybook": "^7.6.17",
"storybook-dark-mode": "^3.0.3",
"typescript": "^5.0.4",
"vite": "^4.4.4",
Expand Down
16 changes: 8 additions & 8 deletions src/components/fui-checkbox/fui-checkbox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const meta = {
},
argTypes: {
checked: { name: '🔗 checked' },
intermediate: { name: '🔗 intermediate' },
indeterminate: { name: '🔗 indeterminate' },
disabled: { name: '🔗 disabled' },
checkLabel: { name: '🔗 checkLabel' },
className: {
Expand Down Expand Up @@ -63,10 +63,10 @@ export const Disabled: Story = {
<div style={{ display: 'flex', gap: 'var(--fui-space-md)' }}>
<FuiCheckbox {...args} disabled />
<FuiCheckbox {...args} checked disabled />
<FuiCheckbox {...args} intermediate disabled />
<FuiCheckbox {...args} indeterminate disabled />
<FuiCheckbox {...args} checkLabel='Label' disabled />
<FuiCheckbox {...args} checkLabel='Label' checked disabled />
<FuiCheckbox {...args} checkLabel='Label' intermediate disabled />
<FuiCheckbox {...args} checkLabel='Label' indeterminate disabled />
</div>
);
},
Expand All @@ -90,15 +90,15 @@ export const Disabled: Story = {
disable: true
}
},
intermediate: {
indeterminate: {
table: {
disable: true
}
}
}
};

export const Intermediate: Story = {
export const Indeterminate: Story = {
render: (args) => {
const [checked1, setChecked1] = React.useState<boolean>(true);
const [checked2, setChecked2] = React.useState<boolean>(false);
Expand All @@ -115,7 +115,7 @@ export const Intermediate: Story = {

return (
<>
<FuiCheckbox {...args} checked={checked1 && checked2} intermediate={checked1 || checked2} onToggle={onToggleMaster} />
<FuiCheckbox {...args} checked={checked1 && checked2} indeterminate={checked1 || checked2} onToggle={onToggleMaster} />
<div style={{ marginLeft: 'var(--fui-space-xxlg)', display: 'flex', flexDirection: 'column', gap: 'var(--fui-space-md)' }}>
<FuiCheckbox {...args} checked={checked1} onToggle={setChecked1} />
<FuiCheckbox {...args} checked={checked2} onToggle={setChecked2} />
Expand All @@ -131,7 +131,7 @@ export const Intermediate: Story = {
url: 'https://www.figma.com/file/zHutj6e9DcPngHZTDtAL1u/Functional-UI-Kit?type=design&node-id=2461-15326'
}
},
name: 'Intermediate',
name: 'Indeterminate',
argTypes: {
disabled: {
table: {
Expand All @@ -143,7 +143,7 @@ export const Intermediate: Story = {
disable: true
}
},
intermediate: {
indeterminate: {
table: {
disable: true
}
Expand Down
8 changes: 4 additions & 4 deletions src/components/fui-checkbox/fui-checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import React from 'react';
import { prefix } from '../prefix';
import FuiIconCheck12X12 from '../../icons/fui-icon-check-12x12';
import classnames from 'classnames';
import FuiIconIntermediateLine2x10 from '../../icons/fui-icon-intermediate-line-2x10';
import FuiIconIndeterminateLine2x10 from '../../icons/fui-icon-indeterminate-line-2x10';

const compPrefix = `${prefix}-checkbox`;

export interface FuiCheckboxProps {
checked?: boolean
intermediate?: boolean
indeterminate?: boolean
disabled?: boolean
onToggle: (isChecked: boolean) => void
checkLabel?: string
Expand All @@ -22,7 +22,7 @@ export const FuiCheckbox = (props: FuiCheckboxProps) => {
`${compPrefix}-wrapper`,
props.disabled ? `${prefix}-disabled` : `${prefix}-interactable`,
props.className,
(props.checked || props.intermediate) ? 'checked' : ''
(props.checked || props.indeterminate) ? 'checked' : ''
);

const onClick = (e: React.MouseEvent<HTMLDivElement>) => {
Expand All @@ -41,7 +41,7 @@ export const FuiCheckbox = (props: FuiCheckboxProps) => {
return (
<div aria-label={props.ariaLabel} tabIndex={0} onKeyDown={onSpace} className={classNames} onClick={onClick}>
<div role='checkbox' className={compPrefix} >
{props.checked ? <FuiIconCheck12X12 /> : props.intermediate ? <FuiIconIntermediateLine2x10 /> : null}
{props.checked ? <FuiIconCheck12X12 /> : props.indeterminate ? <FuiIconIndeterminateLine2x10 /> : null}
</div>
{props.checkLabel && <label>{props.checkLabel}</label>}
</div>
Expand Down
9 changes: 6 additions & 3 deletions src/components/fui-radio/fui-radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ const compPrefix = `${prefix}-radio`;
export const FuiRadio = (props: FuiRadioProps) => {
const [focused, setFocused] = React.useState(false);
const ref = React.useRef<HTMLInputElement>(null);
const inputId = React.useMemo(() => `${compPrefix}-input-${Math.random().toString(36).substring(7)}`, []);
const labelId = React.useMemo(() => `${compPrefix}-label-${Math.random().toString(36).substring(7)}`, []);

const indicatorClassNames = classnames(
`${compPrefix}-indicator`,
props.className,
Expand Down Expand Up @@ -48,11 +51,11 @@ export const FuiRadio = (props: FuiRadioProps) => {
return (
<div aria-label={props.ariaLabel} role='radio' className={classNames} onClick={onClick}>
<div role='radio' className={indicatorClassNames} onClick={onClick}>
<input onKeyDown={onSpace} onBlur={() => { setFocused(false); }} onFocus={() => { setFocused(true); }} disabled={props.disabled} onChange={props.onClick} ref={ref} type='radio' style={{ height: 0 }} />
<input id={inputId} aria-labelledby={labelId} onKeyDown={onSpace} onBlur={() => { setFocused(false); }} onFocus={() => { setFocused(true); }} disabled={props.disabled} onChange={props.onClick} ref={ref} type='radio' style={{ height: 0 }} />
</div>
{props.label && <span className={`${compPrefix}-label`}>
{props.label && <label id={labelId} htmlFor={inputId} className={`${compPrefix}-label`}>
{props.label}
</span>}
</label>}
</div>
);
};
7 changes: 5 additions & 2 deletions src/components/fui-stepper/fui-stepper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ export interface FuiStepperProps {
}

export const FuiStepper = (props: FuiStepperProps) => {
const inputId = React.useMemo(() => `${compPrefix}-input-${Math.random().toString(36).substring(7)}`, []);
const labelId = React.useMemo(() => `${compPrefix}-label-${Math.random().toString(36).substring(7)}`, []);

const isIncDisabled = React.useMemo(() => {
return props.disabled && [FuiStepperDisabled.All, FuiStepperDisabled.Plus].includes(props.disabled);
}, [props.disabled]);
Expand Down Expand Up @@ -73,14 +76,14 @@ export const FuiStepper = (props: FuiStepperProps) => {

return (
<div className={classNames}>
{props.label && <div className={`${compPrefix}-label`}>{props.label}</div>}
{props.label && <label id={labelId} htmlFor={inputId} className={`${compPrefix}-label`}>{props.label}</label>}
{props.status && <FuiStatusMessage {...props.status} />}
<div className={`${compPrefix}-container`} style={containerStyle}>
<button onClick={dec} className={minusButtonClassNames} disabled={isDecDisabled}>
<FuiIconMinus12x12 />
</button>
<div className={valueContainerClassNames}>
<input type="number" className={`${compPrefix}-input`} value={props.value} onChange={(e) => { props.onChange(Number(e.target.value)); }} disabled={isAllDisabled} />
<input id={inputId} aria-labelledby={labelId} type="number" className={`${compPrefix}-input`} value={props.value} onChange={(e) => { props.onChange(Number(e.target.value)); }} disabled={isAllDisabled} />
</div>
<button onClick={inc} className={plusButtonClassNames} disabled={isIncDisabled}>
<FuiIconPlus12x12 />
Expand Down
7 changes: 6 additions & 1 deletion src/components/fui-text-input/fui-text-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export interface FuiTextInputProps {

export const FuiTextInput = (props: FuiTextInputProps) => {
const [isActive, setIsActive] = React.useState(false);
const inputId = React.useMemo(() => `${compPrefix}-input-${Math.random().toString(36).substring(7)}`, []);
const labelId = React.useMemo(() => `${compPrefix}-label-${Math.random().toString(36).substring(7)}`, []);

const clearValue = React.useCallback(() => {
props.onChange('');
Expand All @@ -40,14 +42,17 @@ export const FuiTextInput = (props: FuiTextInputProps) => {
}
);


return (
<div className={`${compPrefix}-wrapper ${props.className}`}>
{props.label ? <div className={`${compPrefix}-label`}>{props.label}</div> : null}
{props.label ? <label id={labelId} htmlFor={inputId} className={`${compPrefix}-label`}>{props.label}</label> : null}
{props.status ? <FuiStatusMessage {...props.status} /> : null}
<div className={`${compPrefix}-container ${props.disabled ? `${prefix}-disabled` : ''}`}>
{props.prefix ? <div className={`${compPrefix}-prefix`}>{props.prefix}</div> : null}
<div className={inputContainerClassNames}>
<input
id={inputId}
aria-labelledby={labelId}
aria-label={props.ariaLabel}
type="text"
value={props.value}
Expand Down
2 changes: 1 addition & 1 deletion src/components/fui-toggle/fui-toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const FuiToggle = (props: FuiToggleProps) => {

return (
<fieldset aria-label={props.ariaLabel} className={classNames}>
<div className={`${compPrefix}-active-bg`} style={{ width: `${activeTabWidth}px`, left: `${activeTabLeftLocation}px` }}/>
<div className={`${compPrefix}-active-bg`} style={{ width: `${activeTabWidth}px`, left: `${activeTabLeftLocation}px` }} />
{props.options.map((option) => {
const onChange = () => {
if (props.disabled) return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import { prefix } from '../components/prefix';

export default function FuiIconIntermediateLine2x10 () {
export default function FuiIconIndeterminateLine2x10 () {
return (
<svg className={`${prefix}-icon-intermediate-line-2x10`} width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
<svg className={`${prefix}-icon-indeterminate-line-2x10`} width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
<path d="M4 9C4 8.44772 4.44772 8 5 8H13C13.5523 8 14 8.44772 14 9C14 9.55228 13.5523 10 13 10H5C4.44772 10 4 9.55228 4 9Z" fill="currentcolor" />
</svg>
);
Expand Down
4 changes: 2 additions & 2 deletions src/icons/icons.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import FuiIconPlaceholder32X32 from './fui-icon-placeholder-32x32';
import FuiIconX12x12 from './fui-icon-x-12x12';
import FuiIconX8x8 from './fui-icon-x-8x8';
import FuiIconX16x16 from './fui-icon-x-16x16';
import FuiIconIntermediateLine2x10 from './fui-icon-intermediate-line-2x10';
import FuiIconIndeterminateLine2x10 from './fui-icon-indeterminate-line-2x10';

const meta = {
title: ' Components/Icons'
Expand All @@ -31,4 +31,4 @@ export const Placeholder32X32: Story = { render: () => <FuiIconPlaceholder32X32/
export const X8x8: Story = { render: () => <FuiIconX8x8/> };
export const X12x12: Story = { render: () => <FuiIconX12x12/> };
export const X16x16: Story = { render: () => <FuiIconX16x16/> };
export const IntermediateLine2x10: Story = { render: () => <FuiIconIntermediateLine2x10/> };
export const IndeterminateLine2x10: Story = { render: () => <FuiIconIndeterminateLine2x10/> };