@handijit/ui 0.0.0-stage → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +786 -2
- package/build/base.css +1 -0
- package/build/charts.cjs +2 -0
- package/build/charts.cjs.map +1 -0
- package/build/charts.css +1 -0
- package/build/charts.js +1866 -0
- package/build/charts.js.map +1 -0
- package/build/chat.cjs +4 -0
- package/build/chat.cjs.map +1 -0
- package/build/chat.css +1 -0
- package/build/chat.js +1121 -0
- package/build/chat.js.map +1 -0
- package/build/components/Accordion/index.cjs +2 -0
- package/build/components/Accordion/index.cjs.map +1 -0
- package/build/components/Accordion/index.d.ts +29 -0
- package/build/components/Accordion/index.js +42 -0
- package/build/components/Accordion/index.js.map +1 -0
- package/build/components/Accordion/style.css +1 -0
- package/build/components/Alert/index.cjs +2 -0
- package/build/components/Alert/index.cjs.map +1 -0
- package/build/components/Alert/index.d.ts +15 -0
- package/build/components/Alert/index.js +30 -0
- package/build/components/Alert/index.js.map +1 -0
- package/build/components/Alert/style.css +1 -0
- package/build/components/Avatar/index.cjs +2 -0
- package/build/components/Avatar/index.cjs.map +1 -0
- package/build/components/Avatar/index.d.ts +26 -0
- package/build/components/Avatar/index.js +57 -0
- package/build/components/Avatar/index.js.map +1 -0
- package/build/components/Avatar/style.css +1 -0
- package/build/components/Badge/index.cjs +2 -0
- package/build/components/Badge/index.cjs.map +1 -0
- package/build/components/Badge/index.d.ts +21 -0
- package/build/components/Badge/index.js +26 -0
- package/build/components/Badge/index.js.map +1 -0
- package/build/components/Badge/style.css +1 -0
- package/build/components/BottomSheet/index.cjs +2 -0
- package/build/components/BottomSheet/index.cjs.map +1 -0
- package/build/components/BottomSheet/index.d.ts +21 -0
- package/build/components/BottomSheet/index.js +85 -0
- package/build/components/BottomSheet/index.js.map +1 -0
- package/build/components/BottomSheet/style.css +1 -0
- package/build/components/Breadcrumb/index.cjs +2 -0
- package/build/components/Breadcrumb/index.cjs.map +1 -0
- package/build/components/Breadcrumb/index.d.ts +20 -0
- package/build/components/Breadcrumb/index.js +31 -0
- package/build/components/Breadcrumb/index.js.map +1 -0
- package/build/components/Breadcrumb/style.css +1 -0
- package/build/components/Button/index.cjs +2 -0
- package/build/components/Button/index.cjs.map +1 -0
- package/build/components/Button/index.d.ts +32 -0
- package/build/components/Button/index.js +88 -0
- package/build/components/Button/index.js.map +1 -0
- package/build/components/Button/style.css +1 -0
- package/build/components/Card/index.cjs +2 -0
- package/build/components/Card/index.cjs.map +1 -0
- package/build/components/Card/index.d.ts +51 -0
- package/build/components/Card/index.js +58 -0
- package/build/components/Card/index.js.map +1 -0
- package/build/components/Card/style.css +1 -0
- package/build/components/Carousel/index.cjs +2 -0
- package/build/components/Carousel/index.cjs.map +1 -0
- package/build/components/Carousel/index.d.ts +24 -0
- package/build/components/Carousel/index.js +111 -0
- package/build/components/Carousel/index.js.map +1 -0
- package/build/components/Carousel/style.css +1 -0
- package/build/components/Checkbox/index.cjs +2 -0
- package/build/components/Checkbox/index.cjs.map +1 -0
- package/build/components/Checkbox/index.d.ts +10 -0
- package/build/components/Checkbox/index.js +33 -0
- package/build/components/Checkbox/index.js.map +1 -0
- package/build/components/Checkbox/style.css +1 -0
- package/build/components/Chip/index.cjs +2 -0
- package/build/components/Chip/index.cjs.map +1 -0
- package/build/components/Chip/index.d.ts +27 -0
- package/build/components/Chip/index.js +67 -0
- package/build/components/Chip/index.js.map +1 -0
- package/build/components/Chip/style.css +1 -0
- package/build/components/ChipGroup/index.cjs +2 -0
- package/build/components/ChipGroup/index.cjs.map +1 -0
- package/build/components/ChipGroup/index.d.ts +34 -0
- package/build/components/ChipGroup/index.js +64 -0
- package/build/components/ChipGroup/index.js.map +1 -0
- package/build/components/ChipGroup/style.css +1 -0
- package/build/components/CodeBadge/index.cjs +2 -0
- package/build/components/CodeBadge/index.cjs.map +1 -0
- package/build/components/CodeBadge/index.d.ts +36 -0
- package/build/components/CodeBadge/index.js +62 -0
- package/build/components/CodeBadge/index.js.map +1 -0
- package/build/components/CodeBadge/style.css +1 -0
- package/build/components/Combobox/index.cjs +2 -0
- package/build/components/Combobox/index.cjs.map +1 -0
- package/build/components/Combobox/index.d.ts +6 -0
- package/build/components/Combobox/index.js +302 -0
- package/build/components/Combobox/index.js.map +1 -0
- package/build/components/Combobox/style.css +1 -0
- package/build/components/CommandPalette/index.cjs +2 -0
- package/build/components/CommandPalette/index.cjs.map +1 -0
- package/build/components/CommandPalette/index.d.ts +37 -0
- package/build/components/CommandPalette/index.js +181 -0
- package/build/components/CommandPalette/index.js.map +1 -0
- package/build/components/CommandPalette/style.css +1 -0
- package/build/components/ConfirmDialog/index.cjs +2 -0
- package/build/components/ConfirmDialog/index.cjs.map +1 -0
- package/build/components/ConfirmDialog/index.d.ts +34 -0
- package/build/components/ConfirmDialog/index.js +85 -0
- package/build/components/ConfirmDialog/index.js.map +1 -0
- package/build/components/CopyField/index.cjs +2 -0
- package/build/components/CopyField/index.cjs.map +1 -0
- package/build/components/CopyField/index.d.ts +20 -0
- package/build/components/CopyField/index.js +44 -0
- package/build/components/CopyField/index.js.map +1 -0
- package/build/components/CopyField/style.css +1 -0
- package/build/components/DataTable/index.cjs +2 -0
- package/build/components/DataTable/index.cjs.map +1 -0
- package/build/components/DataTable/index.d.ts +60 -0
- package/build/components/DataTable/index.js +109 -0
- package/build/components/DataTable/index.js.map +1 -0
- package/build/components/DataTable/style.css +1 -0
- package/build/components/DateField/index.cjs +2 -0
- package/build/components/DateField/index.cjs.map +1 -0
- package/build/components/DateField/index.d.ts +44 -0
- package/build/components/DateField/index.js +79 -0
- package/build/components/DateField/index.js.map +1 -0
- package/build/components/DateField/style.css +1 -0
- package/build/components/Directory/index.cjs +2 -0
- package/build/components/Directory/index.cjs.map +1 -0
- package/build/components/Directory/index.d.ts +51 -0
- package/build/components/Directory/index.js +46 -0
- package/build/components/Directory/index.js.map +1 -0
- package/build/components/Directory/style.css +1 -0
- package/build/components/Disclosure/index.cjs +2 -0
- package/build/components/Disclosure/index.cjs.map +1 -0
- package/build/components/Disclosure/index.d.ts +34 -0
- package/build/components/Disclosure/index.js +64 -0
- package/build/components/Disclosure/index.js.map +1 -0
- package/build/components/Disclosure/style.css +1 -0
- package/build/components/Divider/index.cjs +2 -0
- package/build/components/Divider/index.cjs.map +1 -0
- package/build/components/Divider/index.d.ts +10 -0
- package/build/components/Divider/index.js +24 -0
- package/build/components/Divider/index.js.map +1 -0
- package/build/components/Divider/style.css +1 -0
- package/build/components/Drawer/index.cjs +2 -0
- package/build/components/Drawer/index.cjs.map +1 -0
- package/build/components/Drawer/index.d.ts +22 -0
- package/build/components/Drawer/index.js +88 -0
- package/build/components/Drawer/index.js.map +1 -0
- package/build/components/Drawer/style.css +1 -0
- package/build/components/EmptyState/index.cjs +2 -0
- package/build/components/EmptyState/index.cjs.map +1 -0
- package/build/components/EmptyState/index.d.ts +19 -0
- package/build/components/EmptyState/index.js +35 -0
- package/build/components/EmptyState/index.js.map +1 -0
- package/build/components/EmptyState/style.css +1 -0
- package/build/components/Field/index.cjs +2 -0
- package/build/components/Field/index.cjs.map +1 -0
- package/build/components/Field/index.d.ts +31 -0
- package/build/components/Field/index.js +52 -0
- package/build/components/Field/index.js.map +1 -0
- package/build/components/Field/style.css +1 -0
- package/build/components/FileUpload/index.cjs +2 -0
- package/build/components/FileUpload/index.cjs.map +1 -0
- package/build/components/FileUpload/index.d.ts +42 -0
- package/build/components/FileUpload/index.js +145 -0
- package/build/components/FileUpload/index.js.map +1 -0
- package/build/components/FileUpload/style.css +1 -0
- package/build/components/FilterBar/index.cjs +2 -0
- package/build/components/FilterBar/index.cjs.map +1 -0
- package/build/components/FilterBar/index.d.ts +28 -0
- package/build/components/FilterBar/index.js +35 -0
- package/build/components/FilterBar/index.js.map +1 -0
- package/build/components/FilterBar/style.css +1 -0
- package/build/components/IconButton/index.cjs +2 -0
- package/build/components/IconButton/index.cjs.map +1 -0
- package/build/components/IconButton/index.d.ts +22 -0
- package/build/components/IconButton/index.js +61 -0
- package/build/components/IconButton/index.js.map +1 -0
- package/build/components/IconButton/style.css +1 -0
- package/build/components/Input/index.cjs +2 -0
- package/build/components/Input/index.cjs.map +1 -0
- package/build/components/Input/index.d.ts +15 -0
- package/build/components/Input/index.js +52 -0
- package/build/components/Input/index.js.map +1 -0
- package/build/components/Input/style.css +1 -0
- package/build/components/Kbd/index.cjs +2 -0
- package/build/components/Kbd/index.cjs.map +1 -0
- package/build/components/Kbd/index.d.ts +12 -0
- package/build/components/Kbd/index.js +13 -0
- package/build/components/Kbd/index.js.map +1 -0
- package/build/components/Kbd/style.css +1 -0
- package/build/components/Link/index.cjs +2 -0
- package/build/components/Link/index.cjs.map +1 -0
- package/build/components/Link/index.d.ts +5 -0
- package/build/components/Link/index.js +11 -0
- package/build/components/Link/index.js.map +1 -0
- package/build/components/Menu/index.cjs +2 -0
- package/build/components/Menu/index.cjs.map +1 -0
- package/build/components/Menu/index.d.ts +46 -0
- package/build/components/Menu/index.js +241 -0
- package/build/components/Menu/index.js.map +1 -0
- package/build/components/Menu/style.css +1 -0
- package/build/components/Modal/index.cjs +2 -0
- package/build/components/Modal/index.cjs.map +1 -0
- package/build/components/Modal/index.d.ts +28 -0
- package/build/components/Modal/index.js +92 -0
- package/build/components/Modal/index.js.map +1 -0
- package/build/components/Modal/style.css +1 -0
- package/build/components/PageHeader/index.cjs +2 -0
- package/build/components/PageHeader/index.cjs.map +1 -0
- package/build/components/PageHeader/index.d.ts +24 -0
- package/build/components/PageHeader/index.js +34 -0
- package/build/components/PageHeader/index.js.map +1 -0
- package/build/components/PageHeader/style.css +1 -0
- package/build/components/Pagination/index.cjs +2 -0
- package/build/components/Pagination/index.cjs.map +1 -0
- package/build/components/Pagination/index.d.ts +39 -0
- package/build/components/Pagination/index.js +128 -0
- package/build/components/Pagination/index.js.map +1 -0
- package/build/components/Pagination/style.css +1 -0
- package/build/components/Panel/index.cjs +2 -0
- package/build/components/Panel/index.cjs.map +1 -0
- package/build/components/Panel/index.d.ts +43 -0
- package/build/components/Panel/index.js +55 -0
- package/build/components/Panel/index.js.map +1 -0
- package/build/components/Panel/style.css +1 -0
- package/build/components/PasswordInput/index.cjs +2 -0
- package/build/components/PasswordInput/index.cjs.map +1 -0
- package/build/components/PasswordInput/index.d.ts +14 -0
- package/build/components/PasswordInput/index.js +40 -0
- package/build/components/PasswordInput/index.js.map +1 -0
- package/build/components/PasswordInput/style.css +1 -0
- package/build/components/Popover/index.cjs +2 -0
- package/build/components/Popover/index.cjs.map +1 -0
- package/build/components/Popover/index.d.ts +20 -0
- package/build/components/Popover/index.js +91 -0
- package/build/components/Popover/index.js.map +1 -0
- package/build/components/Popover/style.css +1 -0
- package/build/components/Price/index.cjs +2 -0
- package/build/components/Price/index.cjs.map +1 -0
- package/build/components/Price/index.d.ts +22 -0
- package/build/components/Price/index.js +46 -0
- package/build/components/Price/index.js.map +1 -0
- package/build/components/Price/style.css +1 -0
- package/build/components/Progress/index.cjs +2 -0
- package/build/components/Progress/index.cjs.map +1 -0
- package/build/components/Progress/index.d.ts +49 -0
- package/build/components/Progress/index.js +120 -0
- package/build/components/Progress/index.js.map +1 -0
- package/build/components/Progress/style.css +1 -0
- package/build/components/PromptDialog/index.cjs +2 -0
- package/build/components/PromptDialog/index.cjs.map +1 -0
- package/build/components/PromptDialog/index.d.ts +36 -0
- package/build/components/PromptDialog/index.js +119 -0
- package/build/components/PromptDialog/index.js.map +1 -0
- package/build/components/PromptDialog/style.css +1 -0
- package/build/components/QuantityStepper/index.cjs +2 -0
- package/build/components/QuantityStepper/index.cjs.map +1 -0
- package/build/components/QuantityStepper/index.d.ts +21 -0
- package/build/components/QuantityStepper/index.js +106 -0
- package/build/components/QuantityStepper/index.js.map +1 -0
- package/build/components/QuantityStepper/style.css +1 -0
- package/build/components/Radio/index.cjs +2 -0
- package/build/components/Radio/index.cjs.map +1 -0
- package/build/components/Radio/index.d.ts +12 -0
- package/build/components/Radio/index.js +35 -0
- package/build/components/Radio/index.js.map +1 -0
- package/build/components/Radio/style.css +1 -0
- package/build/components/RadioCard/index.cjs +2 -0
- package/build/components/RadioCard/index.cjs.map +1 -0
- package/build/components/RadioCard/index.d.ts +16 -0
- package/build/components/RadioCard/index.js +48 -0
- package/build/components/RadioCard/index.js.map +1 -0
- package/build/components/RadioCard/style.css +1 -0
- package/build/components/RangeSlider/index.cjs +2 -0
- package/build/components/RangeSlider/index.cjs.map +1 -0
- package/build/components/RangeSlider/index.d.ts +26 -0
- package/build/components/RangeSlider/index.js +102 -0
- package/build/components/RangeSlider/index.js.map +1 -0
- package/build/components/RangeSlider/style.css +1 -0
- package/build/components/Rating/index.cjs +2 -0
- package/build/components/Rating/index.cjs.map +1 -0
- package/build/components/Rating/index.d.ts +16 -0
- package/build/components/Rating/index.js +29 -0
- package/build/components/Rating/index.js.map +1 -0
- package/build/components/Rating/style.css +1 -0
- package/build/components/RatingInput/index.cjs +2 -0
- package/build/components/RatingInput/index.cjs.map +1 -0
- package/build/components/RatingInput/index.d.ts +21 -0
- package/build/components/RatingInput/index.js +75 -0
- package/build/components/RatingInput/index.js.map +1 -0
- package/build/components/RatingInput/style.css +1 -0
- package/build/components/ScrollArea/index.cjs +2 -0
- package/build/components/ScrollArea/index.cjs.map +1 -0
- package/build/components/ScrollArea/index.d.ts +23 -0
- package/build/components/ScrollArea/index.js +65 -0
- package/build/components/ScrollArea/index.js.map +1 -0
- package/build/components/ScrollArea/style.css +1 -0
- package/build/components/SectionHeader/index.cjs +2 -0
- package/build/components/SectionHeader/index.cjs.map +1 -0
- package/build/components/SectionHeader/index.d.ts +17 -0
- package/build/components/SectionHeader/index.js +25 -0
- package/build/components/SectionHeader/index.js.map +1 -0
- package/build/components/SectionHeader/style.css +1 -0
- package/build/components/SegmentedControl/index.cjs +2 -0
- package/build/components/SegmentedControl/index.cjs.map +1 -0
- package/build/components/SegmentedControl/index.d.ts +24 -0
- package/build/components/SegmentedControl/index.js +69 -0
- package/build/components/SegmentedControl/index.js.map +1 -0
- package/build/components/SegmentedControl/style.css +1 -0
- package/build/components/Select/index.cjs +2 -0
- package/build/components/Select/index.cjs.map +1 -0
- package/build/components/Select/index.d.ts +39 -0
- package/build/components/Select/index.js +179 -0
- package/build/components/Select/index.js.map +1 -0
- package/build/components/Select/style.css +1 -0
- package/build/components/Skeleton/index.cjs +2 -0
- package/build/components/Skeleton/index.cjs.map +1 -0
- package/build/components/Skeleton/index.d.ts +25 -0
- package/build/components/Skeleton/index.js +50 -0
- package/build/components/Skeleton/index.js.map +1 -0
- package/build/components/Skeleton/style.css +1 -0
- package/build/components/Spinner/index.cjs +2 -0
- package/build/components/Spinner/index.cjs.map +1 -0
- package/build/components/Spinner/index.d.ts +11 -0
- package/build/components/Spinner/index.js +15 -0
- package/build/components/Spinner/index.js.map +1 -0
- package/build/components/Spinner/style.css +1 -0
- package/build/components/Stat/index.cjs +2 -0
- package/build/components/Stat/index.cjs.map +1 -0
- package/build/components/Stat/index.d.ts +34 -0
- package/build/components/Stat/index.js +72 -0
- package/build/components/Stat/index.js.map +1 -0
- package/build/components/Stat/style.css +1 -0
- package/build/components/StatusDot/index.cjs +2 -0
- package/build/components/StatusDot/index.cjs.map +1 -0
- package/build/components/StatusDot/index.d.ts +23 -0
- package/build/components/StatusDot/index.js +23 -0
- package/build/components/StatusDot/index.js.map +1 -0
- package/build/components/StatusDot/style.css +1 -0
- package/build/components/Steps/index.cjs +2 -0
- package/build/components/Steps/index.cjs.map +1 -0
- package/build/components/Steps/index.d.ts +23 -0
- package/build/components/Steps/index.js +69 -0
- package/build/components/Steps/index.js.map +1 -0
- package/build/components/Steps/style.css +1 -0
- package/build/components/SummaryCard/index.cjs +2 -0
- package/build/components/SummaryCard/index.cjs.map +1 -0
- package/build/components/SummaryCard/index.d.ts +24 -0
- package/build/components/SummaryCard/index.js +33 -0
- package/build/components/SummaryCard/index.js.map +1 -0
- package/build/components/SummaryCard/style.css +1 -0
- package/build/components/Switch/index.cjs +2 -0
- package/build/components/Switch/index.cjs.map +1 -0
- package/build/components/Switch/index.d.ts +16 -0
- package/build/components/Switch/index.js +42 -0
- package/build/components/Switch/index.js.map +1 -0
- package/build/components/Switch/style.css +1 -0
- package/build/components/Table/index.cjs +2 -0
- package/build/components/Table/index.cjs.map +1 -0
- package/build/components/Table/index.d.ts +28 -0
- package/build/components/Table/index.js +58 -0
- package/build/components/Table/index.js.map +1 -0
- package/build/components/Table/style.css +1 -0
- package/build/components/TableCheckbox/index.cjs +2 -0
- package/build/components/TableCheckbox/index.cjs.map +1 -0
- package/build/components/TableCheckbox/index.d.ts +15 -0
- package/build/components/TableCheckbox/index.js +31 -0
- package/build/components/TableCheckbox/index.js.map +1 -0
- package/build/components/TableCheckbox/style.css +1 -0
- package/build/components/Tabs/index.cjs +2 -0
- package/build/components/Tabs/index.cjs.map +1 -0
- package/build/components/Tabs/index.d.ts +27 -0
- package/build/components/Tabs/index.js +102 -0
- package/build/components/Tabs/index.js.map +1 -0
- package/build/components/Tabs/style.css +1 -0
- package/build/components/TagInput/index.cjs +2 -0
- package/build/components/TagInput/index.cjs.map +1 -0
- package/build/components/TagInput/index.d.ts +25 -0
- package/build/components/TagInput/index.js +124 -0
- package/build/components/TagInput/index.js.map +1 -0
- package/build/components/TagInput/style.css +1 -0
- package/build/components/TextLink/index.cjs +2 -0
- package/build/components/TextLink/index.cjs.map +1 -0
- package/build/components/TextLink/index.d.ts +16 -0
- package/build/components/TextLink/index.js +32 -0
- package/build/components/TextLink/index.js.map +1 -0
- package/build/components/TextLink/style.css +1 -0
- package/build/components/Textarea/index.cjs +2 -0
- package/build/components/Textarea/index.cjs.map +1 -0
- package/build/components/Textarea/index.d.ts +20 -0
- package/build/components/Textarea/index.js +68 -0
- package/build/components/Textarea/index.js.map +1 -0
- package/build/components/Textarea/style.css +1 -0
- package/build/components/Tile/index.cjs +2 -0
- package/build/components/Tile/index.cjs.map +1 -0
- package/build/components/Tile/index.d.ts +19 -0
- package/build/components/Tile/index.js +24 -0
- package/build/components/Tile/index.js.map +1 -0
- package/build/components/Tile/style.css +1 -0
- package/build/components/Timeline/index.cjs +2 -0
- package/build/components/Timeline/index.cjs.map +1 -0
- package/build/components/Timeline/index.d.ts +24 -0
- package/build/components/Timeline/index.js +56 -0
- package/build/components/Timeline/index.js.map +1 -0
- package/build/components/Timeline/style.css +1 -0
- package/build/components/Toast/index.cjs +2 -0
- package/build/components/Toast/index.cjs.map +1 -0
- package/build/components/Toast/index.d.ts +43 -0
- package/build/components/Toast/index.js +136 -0
- package/build/components/Toast/index.js.map +1 -0
- package/build/components/Toast/style.css +1 -0
- package/build/components/ToastPortal/index.cjs +2 -0
- package/build/components/ToastPortal/index.cjs.map +1 -0
- package/build/components/ToastPortal/index.d.ts +8 -0
- package/build/components/ToastPortal/index.js +15 -0
- package/build/components/ToastPortal/index.js.map +1 -0
- package/build/components/Tooltip/index.cjs +2 -0
- package/build/components/Tooltip/index.cjs.map +1 -0
- package/build/components/Tooltip/index.d.ts +23 -0
- package/build/components/Tooltip/index.js +116 -0
- package/build/components/Tooltip/index.js.map +1 -0
- package/build/components/Tooltip/style.css +1 -0
- package/build/constants/breakpoint.constants.cjs +2 -0
- package/build/constants/breakpoint.constants.cjs.map +1 -0
- package/build/constants/breakpoint.constants.d.ts +13 -0
- package/build/constants/breakpoint.constants.js +11 -0
- package/build/constants/breakpoint.constants.js.map +1 -0
- package/build/constants/combobox.constants.cjs +2 -0
- package/build/constants/combobox.constants.cjs.map +1 -0
- package/build/constants/combobox.constants.d.ts +11 -0
- package/build/constants/combobox.constants.js +7 -0
- package/build/constants/combobox.constants.js.map +1 -0
- package/build/constants/scroll.constants.cjs +2 -0
- package/build/constants/scroll.constants.cjs.map +1 -0
- package/build/constants/scroll.constants.d.ts +7 -0
- package/build/constants/scroll.constants.js +5 -0
- package/build/constants/scroll.constants.js.map +1 -0
- package/build/enums/ui-size.enum.cjs +2 -0
- package/build/enums/ui-size.enum.cjs.map +1 -0
- package/build/enums/ui-size.enum.d.ts +12 -0
- package/build/enums/ui-size.enum.js +5 -0
- package/build/enums/ui-size.enum.js.map +1 -0
- package/build/enums/ui-variant.enum.cjs +2 -0
- package/build/enums/ui-variant.enum.cjs.map +1 -0
- package/build/enums/ui-variant.enum.d.ts +20 -0
- package/build/enums/ui-variant.enum.js +5 -0
- package/build/enums/ui-variant.enum.js.map +1 -0
- package/build/helpers/class-name.helper.cjs +2 -0
- package/build/helpers/class-name.helper.cjs.map +1 -0
- package/build/helpers/class-name.helper.d.ts +3 -0
- package/build/helpers/class-name.helper.js +10 -0
- package/build/helpers/class-name.helper.js.map +1 -0
- package/build/helpers/component.helper.cjs +2 -0
- package/build/helpers/component.helper.cjs.map +1 -0
- package/build/helpers/component.helper.d.ts +13 -0
- package/build/helpers/component.helper.js +5 -0
- package/build/helpers/component.helper.js.map +1 -0
- package/build/helpers/focus.helper.cjs +2 -0
- package/build/helpers/focus.helper.cjs.map +1 -0
- package/build/helpers/focus.helper.d.ts +42 -0
- package/build/helpers/focus.helper.js +65 -0
- package/build/helpers/focus.helper.js.map +1 -0
- package/build/helpers/label.helper.cjs +2 -0
- package/build/helpers/label.helper.cjs.map +1 -0
- package/build/helpers/label.helper.d.ts +11 -0
- package/build/helpers/label.helper.js +11 -0
- package/build/helpers/label.helper.js.map +1 -0
- package/build/helpers/portal.helper.cjs +2 -0
- package/build/helpers/portal.helper.cjs.map +1 -0
- package/build/helpers/portal.helper.d.ts +28 -0
- package/build/helpers/portal.helper.js +36 -0
- package/build/helpers/portal.helper.js.map +1 -0
- package/build/helpers/scroll.helper.cjs +2 -0
- package/build/helpers/scroll.helper.cjs.map +1 -0
- package/build/helpers/scroll.helper.d.ts +8 -0
- package/build/helpers/scroll.helper.js +11 -0
- package/build/helpers/scroll.helper.js.map +1 -0
- package/build/helpers/text.helper.cjs +2 -0
- package/build/helpers/text.helper.cjs.map +1 -0
- package/build/helpers/text.helper.d.ts +5 -0
- package/build/helpers/text.helper.js +6 -0
- package/build/helpers/text.helper.js.map +1 -0
- package/build/helpers/theme.helper.cjs +2 -0
- package/build/helpers/theme.helper.cjs.map +1 -0
- package/build/helpers/theme.helper.d.ts +18 -0
- package/build/helpers/theme.helper.js +37 -0
- package/build/helpers/theme.helper.js.map +1 -0
- package/build/hooks/useAnnounce.cjs +2 -0
- package/build/hooks/useAnnounce.cjs.map +1 -0
- package/build/hooks/useAnnounce.d.ts +4 -0
- package/build/hooks/useAnnounce.js +23 -0
- package/build/hooks/useAnnounce.js.map +1 -0
- package/build/hooks/useAsyncSearch.cjs +2 -0
- package/build/hooks/useAsyncSearch.cjs.map +1 -0
- package/build/hooks/useAsyncSearch.d.ts +11 -0
- package/build/hooks/useAsyncSearch.js +17 -0
- package/build/hooks/useAsyncSearch.js.map +1 -0
- package/build/hooks/useCopyFeedback.cjs +2 -0
- package/build/hooks/useCopyFeedback.cjs.map +1 -0
- package/build/hooks/useCopyFeedback.d.ts +10 -0
- package/build/hooks/useCopyFeedback.js +25 -0
- package/build/hooks/useCopyFeedback.js.map +1 -0
- package/build/hooks/useDismissOnEscape.cjs +2 -0
- package/build/hooks/useDismissOnEscape.cjs.map +1 -0
- package/build/hooks/useDismissOnEscape.d.ts +12 -0
- package/build/hooks/useDismissOnEscape.js +18 -0
- package/build/hooks/useDismissOnEscape.js.map +1 -0
- package/build/hooks/useListboxNavigation.cjs +2 -0
- package/build/hooks/useListboxNavigation.cjs.map +1 -0
- package/build/hooks/useListboxNavigation.d.ts +7 -0
- package/build/hooks/useListboxNavigation.js +53 -0
- package/build/hooks/useListboxNavigation.js.map +1 -0
- package/build/hooks/usePortalSurface.cjs +2 -0
- package/build/hooks/usePortalSurface.cjs.map +1 -0
- package/build/hooks/usePortalSurface.d.ts +25 -0
- package/build/hooks/usePortalSurface.js +19 -0
- package/build/hooks/usePortalSurface.js.map +1 -0
- package/build/hooks/usePositioning.cjs +2 -0
- package/build/hooks/usePositioning.cjs.map +1 -0
- package/build/hooks/usePositioning.d.ts +13 -0
- package/build/hooks/usePositioning.js +74 -0
- package/build/hooks/usePositioning.js.map +1 -0
- package/build/hooks/useScrollLock.cjs +2 -0
- package/build/hooks/useScrollLock.cjs.map +1 -0
- package/build/hooks/useScrollLock.d.ts +2 -0
- package/build/hooks/useScrollLock.js +34 -0
- package/build/hooks/useScrollLock.js.map +1 -0
- package/build/hooks/useSheetViewport.cjs +2 -0
- package/build/hooks/useSheetViewport.cjs.map +1 -0
- package/build/hooks/useSheetViewport.d.ts +6 -0
- package/build/hooks/useSheetViewport.js +29 -0
- package/build/hooks/useSheetViewport.js.map +1 -0
- package/build/hooks/useStickToBottom.cjs +2 -0
- package/build/hooks/useStickToBottom.cjs.map +1 -0
- package/build/hooks/useStickToBottom.d.ts +12 -0
- package/build/hooks/useStickToBottom.js +39 -0
- package/build/hooks/useStickToBottom.js.map +1 -0
- package/build/hooks/useUiTheme.cjs +2 -0
- package/build/hooks/useUiTheme.cjs.map +1 -0
- package/build/hooks/useUiTheme.d.ts +10 -0
- package/build/hooks/useUiTheme.js +42 -0
- package/build/hooks/useUiTheme.js.map +1 -0
- package/build/hooks/useUiTokens.cjs +2 -0
- package/build/hooks/useUiTokens.cjs.map +1 -0
- package/build/hooks/useUiTokens.d.ts +11 -0
- package/build/hooks/useUiTokens.js +36 -0
- package/build/hooks/useUiTokens.js.map +1 -0
- package/build/hooks/useVirtualList.cjs +2 -0
- package/build/hooks/useVirtualList.cjs.map +1 -0
- package/build/hooks/useVirtualList.d.ts +13 -0
- package/build/hooks/useVirtualList.js +41 -0
- package/build/hooks/useVirtualList.js.map +1 -0
- package/build/index.cjs +2 -0
- package/build/index.cjs.map +1 -0
- package/build/index.d.ts +93 -0
- package/build/index.js +199 -0
- package/build/index.js.map +1 -0
- package/build/scss/_index.scss +7 -0
- package/build/scss/_mixins.scss +828 -0
- package/build/scss/_variables.scss +243 -0
- package/build/styles/base.d.ts +0 -0
- package/build/styles.css +133 -0
- package/build/theme/UiProvider.cjs +2 -0
- package/build/theme/UiProvider.cjs.map +1 -0
- package/build/theme/UiProvider.d.ts +23 -0
- package/build/theme/UiProvider.js +12 -0
- package/build/theme/UiProvider.js.map +1 -0
- package/build/theme/UiThemeScript.cjs +2 -0
- package/build/theme/UiThemeScript.cjs.map +1 -0
- package/build/theme/UiThemeScript.d.ts +22 -0
- package/build/theme/UiThemeScript.js +8 -0
- package/build/theme/UiThemeScript.js.map +1 -0
- package/build/theme/context.cjs +2 -0
- package/build/theme/context.cjs.map +1 -0
- package/build/theme/context.d.ts +5 -0
- package/build/theme/context.js +8 -0
- package/build/theme/context.js.map +1 -0
- package/build/types/charts/AreaChart/index.d.ts +14 -0
- package/build/types/charts/BarChart/index.d.ts +16 -0
- package/build/types/charts/BoxPlot/index.d.ts +43 -0
- package/build/types/charts/ComposedChart/index.d.ts +16 -0
- package/build/types/charts/Heatmap/index.d.ts +30 -0
- package/build/types/charts/Histogram/index.d.ts +29 -0
- package/build/types/charts/LineChart/index.d.ts +14 -0
- package/build/types/charts/PieChart/index.d.ts +36 -0
- package/build/types/charts/RadarChart/index.d.ts +40 -0
- package/build/types/charts/ScatterPlot/index.d.ts +41 -0
- package/build/types/charts/core/CartesianChart.d.ts +43 -0
- package/build/types/charts/core/ChartFrame.d.ts +55 -0
- package/build/types/charts/core/axes.d.ts +37 -0
- package/build/types/charts/core/cartesian.d.ts +80 -0
- package/build/types/charts/core/format.d.ts +19 -0
- package/build/types/charts/core/margins.d.ts +9 -0
- package/build/types/charts/core/palette.d.ts +11 -0
- package/build/types/charts/core/path.d.ts +24 -0
- package/build/types/charts/core/scale.d.ts +40 -0
- package/build/types/charts/core/series.d.ts +11 -0
- package/build/types/charts/core/spatial.d.ts +12 -0
- package/build/types/charts/core/stats.d.ts +34 -0
- package/build/types/charts/core/types.d.ts +31 -0
- package/build/types/charts/core/useChartWidth.d.ts +7 -0
- package/build/types/charts/index.d.ts +21 -0
- package/build/types/chat/ActionList/index.d.ts +46 -0
- package/build/types/chat/AppBar/index.d.ts +21 -0
- package/build/types/chat/ChatMessage/index.d.ts +24 -0
- package/build/types/chat/ChatThread/index.d.ts +24 -0
- package/build/types/chat/Citation/index.d.ts +15 -0
- package/build/types/chat/CodeBlock/format.d.ts +7 -0
- package/build/types/chat/CodeBlock/grammars.d.ts +44 -0
- package/build/types/chat/CodeBlock/highlight.d.ts +22 -0
- package/build/types/chat/CodeBlock/index.d.ts +33 -0
- package/build/types/chat/DescriptionList/index.d.ts +16 -0
- package/build/types/chat/Legend/index.d.ts +21 -0
- package/build/types/chat/MessageActions/index.d.ts +21 -0
- package/build/types/chat/PromptInput/index.d.ts +47 -0
- package/build/types/chat/PromptSuggestions/index.d.ts +25 -0
- package/build/types/chat/Prose/index.d.ts +15 -0
- package/build/types/chat/ReasoningBlock/index.d.ts +24 -0
- package/build/types/chat/ReasoningText/index.d.ts +14 -0
- package/build/types/chat/SegmentBar/index.d.ts +46 -0
- package/build/types/chat/SourceList/index.d.ts +25 -0
- package/build/types/chat/TerminalOutput/index.d.ts +25 -0
- package/build/types/chat/ToolCall/index.d.ts +41 -0
- package/build/types/chat/index.d.ts +26 -0
- package/build/types/combobox.type.d.ts +49 -0
- package/build/types/common-element-props.type.d.ts +8 -0
- package/build/types/helpers/class-name.helper.d.ts +3 -0
- package/build/types/helpers/component.helper.d.ts +13 -0
- package/build/types/helpers/label.helper.d.ts +12 -0
- package/build/types/hook.type.d.ts +36 -0
- package/build/types/link.type.d.ts +14 -0
- package/build/types/positioning.type.d.ts +38 -0
- package/build/types/theme.type.d.ts +181 -0
- package/build/types/types/common-element-props.type.d.ts +8 -0
- package/build/types/types/link.type.d.ts +14 -0
- package/build/types/types/theme.type.d.ts +181 -0
- package/package.json +487 -4
package/README.md
CHANGED
|
@@ -1,3 +1,787 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @handijit/ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Accessible React components for Han Dijit applications: the site, the staff
|
|
4
|
+
panel and the desktop programs. Built on SCSS Modules and drawn with the tokens
|
|
5
|
+
of [`@handijit/design`](https://www.npmjs.com/package/@handijit/design).
|
|
6
|
+
|
|
7
|
+
- **One design source.** Colours, type, radii, spacing, motion and layers come
|
|
8
|
+
from `@handijit/design` (`--hd-*`). This package holds no palette of its own.
|
|
9
|
+
- **Light and dark.** Both themes ship; the choice rides on `data-theme`, the
|
|
10
|
+
contract `@handijit/design` defines.
|
|
11
|
+
- **The router is injected.** `next/link`, `react-router`, a plain `<a>`: the
|
|
12
|
+
application decides.
|
|
13
|
+
- **Text comes from outside, once.** The library invents no string in any
|
|
14
|
+
language; user-visible strings are defined in one place, on the provider.
|
|
15
|
+
- **Native elements are kept.** `<dialog>`, `<input type="range">`,
|
|
16
|
+
`<input type="radio">`: focus trapping, keyboard handling and screen reader
|
|
17
|
+
announcements come from the browser.
|
|
18
|
+
- **Three sub-entries, zero bytes in the main bundle.** `@handijit/ui/chat`
|
|
19
|
+
(chat and tool interfaces), `@handijit/ui/charts` (dependency-free SVG
|
|
20
|
+
charts), `@handijit/ui/scss` (token variables and mixins).
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @handijit/ui @handijit/design @handijit/utils react-bootstrap-icons
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`react`, `react-dom`, `@handijit/design` (`^1.0.0`), `@handijit/utils`
|
|
27
|
+
(`^2.0.0`) and `react-bootstrap-icons` are **peer** dependencies. The design
|
|
28
|
+
package is a peer on purpose: an application has exactly one copy of the tokens,
|
|
29
|
+
and the site, the panel and the components all read the same custom properties.
|
|
30
|
+
|
|
31
|
+
Coming from 1.x? The migration is in [`CHANGELOG.md`](./CHANGELOG.md) under
|
|
32
|
+
2.0.0, old name → new name for every token, variable, prop, variant and export.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Quick start
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
// Once, at the root of the application. The order matters.
|
|
40
|
+
import '@handijit/design/tokens.css'; // the --hd-* custom properties, both themes
|
|
41
|
+
import '@handijit/design/fonts.css'; // optional: Archivo, Inter, IBM Plex Mono
|
|
42
|
+
import '@handijit/ui/styles.css';
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
import { Button, Field, Input, UIVariant } from '@handijit/ui';
|
|
47
|
+
|
|
48
|
+
<Field label="E-posta" isRequired error={error}>
|
|
49
|
+
{props => <Input {...props} type="email" value={email} onChange={onChange} />}
|
|
50
|
+
</Field>
|
|
51
|
+
|
|
52
|
+
<Button variant={UIVariant.PRIMARY} isLoading={isSaving} onClick={save}>
|
|
53
|
+
Kaydet
|
|
54
|
+
</Button>;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The provider is **optional**: the package works with no configuration. Links
|
|
58
|
+
are plain `<a>` elements and labels are whatever each call passes.
|
|
59
|
+
|
|
60
|
+
`@handijit/ui/styles.css` carries **no tokens**. Without
|
|
61
|
+
`@handijit/design/tokens.css` every colour resolves to nothing. `fonts.css` is
|
|
62
|
+
optional: load the three families your own way (`next/font`, self-hosted
|
|
63
|
+
`@font-face`) if you prefer, the tokens only name them.
|
|
64
|
+
|
|
65
|
+
### A subset of the CSS
|
|
66
|
+
|
|
67
|
+
An application that wants less imports `base.css` (box model, `@keyframes`,
|
|
68
|
+
helpers) and the `components/<Name>/style.css` files of the components it uses,
|
|
69
|
+
and lets its own build join them:
|
|
70
|
+
|
|
71
|
+
```scss
|
|
72
|
+
// styles/ui.scss: Sass inlines plain CSS files.
|
|
73
|
+
@use '@handijit/ui/base.css';
|
|
74
|
+
@use '@handijit/ui/components/Button/style.css';
|
|
75
|
+
@use '@handijit/ui/components/Chip/style.css';
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The JavaScript modules do not import CSS. That is deliberate: under Turbopack
|
|
79
|
+
every client boundary's CSS landed in its own file, and the number of
|
|
80
|
+
render-blocking files hurt LCP more than the bytes did.
|
|
81
|
+
|
|
82
|
+
Every component also has a subpath (`@handijit/ui/button`, `/chip-group`,
|
|
83
|
+
`/combobox`, …). The main entry is a pure re-export, so a bundler reaches the
|
|
84
|
+
same file either way.
|
|
85
|
+
|
|
86
|
+
The sub-entries have their own stylesheets, imported **after** `styles.css`:
|
|
87
|
+
`@handijit/ui/chat.css`, `@handijit/ui/charts.css`.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Theme
|
|
92
|
+
|
|
93
|
+
### The choice rides on `<html data-theme>`
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<html data-theme="dark"></html>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
This is the contract of `@handijit/design`, not a setting of this package:
|
|
100
|
+
`data-theme="light"` or `"dark"` on the root element picks the theme, and
|
|
101
|
+
without the attribute `prefers-color-scheme` decides. An explicit choice is
|
|
102
|
+
never overridden by the system setting. The attribute also works on any
|
|
103
|
+
element, to draw one region in the other theme.
|
|
104
|
+
|
|
105
|
+
### Write it before the first paint: `UiThemeScript`
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
// app/layout.tsx, a server layout, inside <head>.
|
|
109
|
+
import { UiThemeScript } from '@handijit/ui';
|
|
110
|
+
|
|
111
|
+
<head>
|
|
112
|
+
<UiThemeScript nonce={nonce} />
|
|
113
|
+
</head>;
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
It renders the boot script of `@handijit/design` (`THEME_BOOT_SCRIPT`) as an
|
|
117
|
+
inline `<script>`. The script reads `localStorage["hd-theme"]` (`light` or
|
|
118
|
+
`dark`; anything else means "follow the system"), writes `data-theme` while the
|
|
119
|
+
HTML is still being parsed, and follows the system setting when it changes.
|
|
120
|
+
Without it a user who chose dark sees one light frame.
|
|
121
|
+
|
|
122
|
+
It is a component and not a function because a plain function exported from a
|
|
123
|
+
package with `'use client'` files cannot be called from a Next.js server layout.
|
|
124
|
+
|
|
125
|
+
### Content Security Policy
|
|
126
|
+
|
|
127
|
+
The boot script is the **only** element this library injects. It injects no
|
|
128
|
+
`<style>` element at all.
|
|
129
|
+
|
|
130
|
+
| Policy style | What to do |
|
|
131
|
+
| ----------------- | --------------------------------------------------------------------------- |
|
|
132
|
+
| Nonce per request | `<UiThemeScript nonce={nonce} />` |
|
|
133
|
+
| Static hash | add `'${THEME_BOOT_SCRIPT_HASH}'` to `script-src`; the page stays cacheable |
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
import { THEME_BOOT_SCRIPT_HASH } from '@handijit/ui'; // re-exported from @handijit/design
|
|
137
|
+
|
|
138
|
+
const policy = `script-src 'self' '${THEME_BOOT_SCRIPT_HASH}'`;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`THEME_ATTRIBUTE`, `THEME_STORAGE_KEY`, `THEME_BOOT_SCRIPT` and
|
|
142
|
+
`THEME_BOOT_SCRIPT_HASH` are re-exports, not copies: the digest always matches
|
|
143
|
+
the script the installed design package ships.
|
|
144
|
+
|
|
145
|
+
Some components position or size themselves with inline `style` attributes
|
|
146
|
+
(popover coordinates, progress width, virtual list offsets). A nonce cannot
|
|
147
|
+
cover an attribute; a policy that restricts inline styles needs
|
|
148
|
+
`style-src-attr 'unsafe-inline'`.
|
|
149
|
+
|
|
150
|
+
### Changing the theme
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
const { scheme, preference, setScheme, toggle, isReady } = useUiTheme();
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
| Field | |
|
|
157
|
+
| ------------ | ---------------------------------------------------------------------- |
|
|
158
|
+
| `scheme` | the **resolved** theme, the one on screen (`light` \| `dark`) |
|
|
159
|
+
| `preference` | the user's **choice** (`light` \| `dark` \| `system`) |
|
|
160
|
+
| `setScheme` | stores the choice and applies it; `'system'` removes the stored choice |
|
|
161
|
+
| `toggle` | flips between light and dark |
|
|
162
|
+
| `isReady` | `false` on the server and on the first client frame |
|
|
163
|
+
|
|
164
|
+
A three-state switch (Light / Dark / System) reads `preference`; if it read
|
|
165
|
+
`scheme`, "System" would show "Dark" as selected.
|
|
166
|
+
|
|
167
|
+
`setScheme` writes where the boot script reads: `localStorage["hd-theme"]`
|
|
168
|
+
holds `light` or `dark`, "system" removes the key, and the attribute always
|
|
169
|
+
carries the resolved theme. A choice made through the hook therefore survives a
|
|
170
|
+
reload without a flash. Wait for `isReady` before drawing the switch: the
|
|
171
|
+
server does not know the choice, and a guessed switch mismatched on hydration
|
|
172
|
+
even when the guess was right.
|
|
173
|
+
|
|
174
|
+
### Brand and product overrides
|
|
175
|
+
|
|
176
|
+
There is no theme prop. A value is changed where it is defined, as a custom
|
|
177
|
+
property, in the application's own stylesheet:
|
|
178
|
+
|
|
179
|
+
```css
|
|
180
|
+
:root {
|
|
181
|
+
--hd-radius-md: 10px;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* The same selector the design package uses, or the override loses on <html>. */
|
|
185
|
+
:root[data-theme='dark'] {
|
|
186
|
+
--hd-bg-page: #0b0d12;
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Change the tokens of `@handijit/design` sparingly: the contrast of every text
|
|
191
|
+
and focus pair is measured against the published values.
|
|
192
|
+
|
|
193
|
+
### Overriding our CSS: `@layer ui`
|
|
194
|
+
|
|
195
|
+
All of the library's CSS is inside `@layer ui`. A layered rule **always loses**
|
|
196
|
+
to an unlayered one, whatever the specificity or source order:
|
|
197
|
+
|
|
198
|
+
```css
|
|
199
|
+
/* This is enough; no `!important`, no `.app .card .card`. */
|
|
200
|
+
.my-card {
|
|
201
|
+
padding: 0;
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Without the layer your class and ours competed at the same specificity and the
|
|
206
|
+
winner was decided by source order, which is in your bundler's hands and need
|
|
207
|
+
not be the same in development and production.
|
|
208
|
+
|
|
209
|
+
### Component variables
|
|
210
|
+
|
|
211
|
+
Besides the design tokens, a few components read custom properties of their own
|
|
212
|
+
(`var(--ui-…, default)`) so an application can restyle one component from
|
|
213
|
+
`:root` without a class selector:
|
|
214
|
+
|
|
215
|
+
| Component | Variables |
|
|
216
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
217
|
+
| focus ring | `--ui-ring-width` (2px) · `--ui-ring-offset` (2px; `-2px` pulls it inside) |
|
|
218
|
+
| inputs | `--ui-placeholder` (`text-3`) |
|
|
219
|
+
| modal scrim | `--ui-scrim-blur` |
|
|
220
|
+
| `Button` | `--ui-button-radius` · `-weight` · `-tracking` · `-wrap` (`nowrap`) |
|
|
221
|
+
| `Chip` | `--ui-chip-bg` · `-line` · `-fg` · `-radius` · `-weight` · `-selected-bg` · `-selected-line` · `-selected-fg` · `-selected-weight` |
|
|
222
|
+
| `Badge` | `--ui-badge-font` · `-weight` · `-tracking` · `-transform` · `-radius` · `-bg` · `-line` · `-fg` |
|
|
223
|
+
| `Stat` | `--ui-stat-label-font/-size/-weight/-tracking/-transform` · `-value-font/-weight/-tracking` · `-unit-font/-size/-tracking/-transform` |
|
|
224
|
+
| `Tabs` | `--ui-tab-weight` |
|
|
225
|
+
| `RadioCard` | `--ui-radio-card-line` · `-radius` |
|
|
226
|
+
| sticky parts | `--ui-header-height` (see below) |
|
|
227
|
+
|
|
228
|
+
```css
|
|
229
|
+
:root {
|
|
230
|
+
--ui-ring-offset: -2px;
|
|
231
|
+
--ui-button-weight: 500;
|
|
232
|
+
--ui-chip-radius: var(--hd-radius-pill);
|
|
233
|
+
--ui-badge-font: var(--hd-font-mono);
|
|
234
|
+
--ui-badge-transform: uppercase;
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
`--ui-*` is the prefix of component-private variables only. Every global value
|
|
239
|
+
(colour, size, radius, duration, layer) is `--hd-*`.
|
|
240
|
+
|
|
241
|
+
### Reading tokens in JavaScript
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
const colors = useUiTokens(['border', 'chart-1']); // { border: '#…', 'chart-1': '#…' }
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
`useUiTokens` returns the resolved values of design tokens and follows theme
|
|
248
|
+
changes; it is for canvas and third-party charts that cannot read `var()`. On
|
|
249
|
+
the server and the first frame it returns `currentColor`. The names are
|
|
250
|
+
`TokenName` of `@handijit/design`.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Labels
|
|
255
|
+
|
|
256
|
+
The library cannot write "Close": it does not know the language, the tone or
|
|
257
|
+
the term. Spreading the same string over a hundred call sites is not right
|
|
258
|
+
either. Labels are given **once**, on the provider:
|
|
259
|
+
|
|
260
|
+
```tsx
|
|
261
|
+
<UiProvider
|
|
262
|
+
labels={{
|
|
263
|
+
close: 'Kapat',
|
|
264
|
+
cancel: 'Vazgeç',
|
|
265
|
+
submit: 'Kaydet',
|
|
266
|
+
loading: 'Yükleniyor',
|
|
267
|
+
required: '(zorunlu)',
|
|
268
|
+
filters: 'Filtreler',
|
|
269
|
+
breadcrumb: 'Konum',
|
|
270
|
+
directoryJump: 'Harfe göre atla',
|
|
271
|
+
selectPlaceholder: 'Seçiniz',
|
|
272
|
+
locale: 'tr',
|
|
273
|
+
currency: '₺',
|
|
274
|
+
combobox: {
|
|
275
|
+
searchPlaceholder: 'Ara…',
|
|
276
|
+
emptyMessage: 'Sonuç bulunamadı',
|
|
277
|
+
loadingMessage: 'Aranıyor…',
|
|
278
|
+
clearLabel: 'Seçimi temizle',
|
|
279
|
+
},
|
|
280
|
+
pagination: { label: 'Sayfalar', previous: 'Önceki sayfa', next: 'Sonraki sayfa' },
|
|
281
|
+
quantity: { label: 'Adet', decrease: 'Adeti azalt', increase: 'Adeti artır' },
|
|
282
|
+
range: { min: 'En az', max: 'En çok' },
|
|
283
|
+
dataTable: { empty: 'Kayıt bulunamadı.', loading: 'Yükleniyor…' },
|
|
284
|
+
copyField: {
|
|
285
|
+
copy: value => `${value} kopyala`,
|
|
286
|
+
copied: value => `${value} kopyalandı`,
|
|
287
|
+
announcement: 'Panoya kopyalandı',
|
|
288
|
+
},
|
|
289
|
+
rating: {
|
|
290
|
+
srLabel: (value, count) => `5 üzerinden ${value}${count ? `, ${count} değerlendirme` : ''}`,
|
|
291
|
+
starCount: star => `${star} yıldız`,
|
|
292
|
+
scale: { 1: 'Hiç memnun kalmadım', 2: 'Beklentimi karşılamadı', 3: 'İdare eder', 4: 'Memnun kaldım', 5: 'Çok memnun kaldım' },
|
|
293
|
+
},
|
|
294
|
+
}}
|
|
295
|
+
>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Resolution order: prop → provider → development warning.** A prop wins when
|
|
299
|
+
given; pass one where the wording depends on the context
|
|
300
|
+
(`closeLabel="Daha sonra"`).
|
|
301
|
+
|
|
302
|
+
Text that belongs to **one element** never goes on the provider, because it
|
|
303
|
+
differs at every call site: `Modal.title`, `ConfirmDialog.confirmLabel` ("Sil":
|
|
304
|
+
it must repeat the action; "OK" does not say what is being confirmed),
|
|
305
|
+
`IconButton.label`, `Select.label`, `Combobox.labels.placeholder`,
|
|
306
|
+
`TableCheckbox.label`, `ChipGroup.label`, `RatingInput.label`.
|
|
307
|
+
|
|
308
|
+
TypeScript cannot see what the provider carries at run time, so the props are
|
|
309
|
+
optional. With neither a prop nor a provider value the element stays unnamed
|
|
310
|
+
and, in development, the console says so once per key:
|
|
311
|
+
|
|
312
|
+
```
|
|
313
|
+
[@handijit/ui] Eksik metin: Modal.closeLabel. Prop olarak geçin ya da
|
|
314
|
+
<UiProvider labels={…}> içinde bir kez tanımlayın.
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Router
|
|
320
|
+
|
|
321
|
+
```tsx
|
|
322
|
+
import NextLink from 'next/link';
|
|
323
|
+
|
|
324
|
+
<UiProvider linkComponent={NextLink}>…</UiProvider>;
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
A component library cannot choose the router: importing `next/link` ties the
|
|
328
|
+
package to Next.js, importing `react-router` breaks another application.
|
|
329
|
+
Router-specific props travel through `linkProps`:
|
|
330
|
+
|
|
331
|
+
```tsx
|
|
332
|
+
<Pagination buildHref={page => `?sayfa=${page}`} linkProps={{ scroll: false }} … />
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Back to the top after a page change
|
|
336
|
+
|
|
337
|
+
```tsx
|
|
338
|
+
<Pagination page={page} totalPages={totalPages} scrollTo="top" … />
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
It works in both modes (`buildHref` and `onPageChange`). The scroll is instant
|
|
342
|
+
and does **not** happen when the active page is pressed, when the click opens a
|
|
343
|
+
new tab (Ctrl/Cmd/middle button), or when the prop is absent. Do not pass it
|
|
344
|
+
for a list inside a page (reviews in a tab): it throws the reader to the top.
|
|
345
|
+
|
|
346
|
+
### Sticky header
|
|
347
|
+
|
|
348
|
+
Components that stick while the page scrolls (`DirectoryGroup`,
|
|
349
|
+
`DirectoryJump`, a `DataTable` with a caption) read their offset from
|
|
350
|
+
`--ui-header-height`, **0 by default**. If the application has a sticky band,
|
|
351
|
+
write its real height:
|
|
352
|
+
|
|
353
|
+
```tsx
|
|
354
|
+
useEffect(() => {
|
|
355
|
+
const observer = new ResizeObserver(([entry]) =>
|
|
356
|
+
document.documentElement.style.setProperty(
|
|
357
|
+
'--ui-header-height',
|
|
358
|
+
`${entry.contentRect.height}px`,
|
|
359
|
+
),
|
|
360
|
+
);
|
|
361
|
+
observer.observe(headerRef.current!);
|
|
362
|
+
return () => observer.disconnect();
|
|
363
|
+
}, []);
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Do not write a constant: the band grows when the search box wraps on a phone
|
|
367
|
+
and changes when an announcement strip appears.
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Component catalogue
|
|
372
|
+
|
|
373
|
+
| Group | Components |
|
|
374
|
+
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
375
|
+
| Action | `Button` · `IconButton` · `TextLink` · `Tooltip` · `Menu` · `ContextMenu` · `Popover` |
|
|
376
|
+
| Choice | `Chip` · `ChipGroup` · `SegmentedControl` · `Select` · `Combobox` · `Checkbox` · `Switch` · `Radio` · `RadioCard` · `RangeSlider` · `RatingInput` · `QuantityStepper` · `TableCheckbox` |
|
|
377
|
+
| Input | `Input` · `PasswordInput` · `Textarea` · `TagInput` · `DateField` · `FileUpload` · `Field` |
|
|
378
|
+
| Surface | `Card` (+ `CardMedia`, `CardOverlay`, `CardBody`, `CardFooter`) · `SummaryCard` · `Panel` (+ `PanelForm`, `PanelRow`) · `PageHeader` · `SectionHeader` · `Tile` · `Directory` (+ `DirectoryGroup`, `DirectoryRow`, `DirectoryJump`) · `Carousel` · `ScrollArea` · `Disclosure` · `Accordion` · `Tabs` |
|
|
379
|
+
| Feedback | `Alert` · `Badge` · `StatusDot` · `CodeBadge` · `Kbd` · `EmptyState` · `Skeleton` (+ `SkeletonCard`, `SkeletonRows`, `SkeletonTable`) · `Spinner` · `Progress` · `Steps` · `Divider` · `Avatar` · `Rating` · `Price` · `Stat` · `CopyField` · `Breadcrumb` · `ToastHub` (+ `ToastPortal`) |
|
|
380
|
+
| Modal | `Modal` · `Drawer` · `BottomSheet` · `ConfirmDialog` · `PromptDialog` · `CommandPalette` |
|
|
381
|
+
| Data | `Table` (+ `TableScroller`) · `DataTable` (+ `DataTableRow`) · `FilterBar` (+ `FilterBarField`) · `Pagination` · `Timeline` |
|
|
382
|
+
| Theme and hooks | `UiProvider` · `UiThemeScript` · `useUi` · `useUiTheme` · `useUiTokens` · `useAnnounce` · `useStickToBottom` · `usePositioning` · `useVirtualList` · `useListboxNavigation` · `hasOpenSurface` |
|
|
383
|
+
| Chat, `/chat` | `ChatThread` · `ChatMessage` · `PromptInput` · `PromptSuggestions` · `Prose` · `CodeBlock` · `ReasoningBlock` (+ `ReasoningText`) · `ToolCall` (+ `ToolCallSection`) · `TerminalOutput` · `SourceList` · `Citation` · `MessageActions` · `AppBar` · `ActionList` (+ `ActionListItem`) · `SegmentBar` · `Legend` · `DescriptionList` |
|
|
384
|
+
| Charts, `/charts` | `LineChart` · `AreaChart` · `BarChart` · `ComposedChart` · `PieChart` · `ScatterPlot` · `Heatmap` · `BoxPlot` · `Histogram` · `RadarChart` |
|
|
385
|
+
|
|
386
|
+
### Variants and sizes
|
|
387
|
+
|
|
388
|
+
| `UIVariant` | Use |
|
|
389
|
+
| ----------- | ----------------------------------------------------------------------- |
|
|
390
|
+
| `PRIMARY` | the one expected action of the screen: cobalt fill |
|
|
391
|
+
| `ACCENT` | the conversion action (download, try, subscribe): coral fill, only that |
|
|
392
|
+
| `SECONDARY` | a neutral second action: grey border, body text |
|
|
393
|
+
| `OUTLINE` | a cobalt frame: an encouraged navigation that is not the primary action |
|
|
394
|
+
| `SOFT` | a neutral fill: a secondary action inside a card |
|
|
395
|
+
| `GHOST` | no surface: toolbar and inline secondary actions, in the link colour |
|
|
396
|
+
| `DANGER` | a destructive action |
|
|
397
|
+
| `ON_BAND` | an action on the brand band (deep cobalt in both themes) |
|
|
398
|
+
|
|
399
|
+
`UISize`: `XSMALL` 28px · `SMALL` 32px · `MEDIUM` 40px · `LARGE` 48px. Fields
|
|
400
|
+
are 40px with 15px text on desktop and 44px with 16px text on a narrow or touch
|
|
401
|
+
screen (no iOS zoom, a full touch target).
|
|
402
|
+
|
|
403
|
+
`IconButton variant`: `ghost` · `outline` · `solid` · `accent` · `danger`.
|
|
404
|
+
`Badge tone`: `neutral` · `success` · `danger` · `warning` · `info` ·
|
|
405
|
+
`highlight`, each as `soft`, `solid` or `outline`.
|
|
406
|
+
|
|
407
|
+
### The number of options picks the element
|
|
408
|
+
|
|
409
|
+
| Options | Element |
|
|
410
|
+
| ------------- | ---------------------------------------------------- |
|
|
411
|
+
| ≤7 | `ChipGroup`: all on screen, one tap |
|
|
412
|
+
| 5–20 | `Select`: a list without search |
|
|
413
|
+
| 20+ | `Combobox`: type to search |
|
|
414
|
+
| A range | `RangeSlider` (+ a number input for the exact value) |
|
|
415
|
+
| A single flag | `Checkbox` |
|
|
416
|
+
|
|
417
|
+
### Dropdown or bottom sheet
|
|
418
|
+
|
|
419
|
+
`Select` and `Combobox` open a **dropdown anchored to the trigger** on every
|
|
420
|
+
screen except a narrow touch one, where they open a **bottom sheet**. The rule
|
|
421
|
+
is one media query, exported as `SHEET_MEDIA_QUERY`:
|
|
422
|
+
`(max-width: 640px) and (pointer: coarse)`. A narrow desktop window, an
|
|
423
|
+
Electron window included, keeps the dropdown.
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
## Decisions the system carries
|
|
428
|
+
|
|
429
|
+
**Cobalt acts, coral converts, turquoise highlights.** Cobalt is the primary
|
|
430
|
+
action, the link, the selection and the focus ring. Coral is the conversion
|
|
431
|
+
button (`UIVariant.ACCENT` on `Button`, `variant="accent"` on `IconButton`) and
|
|
432
|
+
appears nowhere else. Turquoise marks a highlight or a live state
|
|
433
|
+
(`Badge tone="highlight"`, `Avatar tone="highlight"`); it is a fill, never body
|
|
434
|
+
text.
|
|
435
|
+
`colour-footprint.test.ts` turns a coral or turquoise token in any other
|
|
436
|
+
component's stylesheet into a failing test.
|
|
437
|
+
|
|
438
|
+
**One `PRIMARY` per screen.** `UIVariant` is a hierarchy of emphasis: two
|
|
439
|
+
filled buttons side by side and neither stands out.
|
|
440
|
+
|
|
441
|
+
**Status is a tint, an action is a fill or a border.** `Alert` and the soft
|
|
442
|
+
`Badge` sit on tinted grounds; when that distinction blurs, users try to click
|
|
443
|
+
status labels.
|
|
444
|
+
|
|
445
|
+
**Colour never carries meaning alone** (WCAG 1.4.1). Every state is also told
|
|
446
|
+
by a text, an icon or a mark: each `Alert` tone has its own icon, the required
|
|
447
|
+
star of `Field` has a readable text next to it.
|
|
448
|
+
|
|
449
|
+
**Icons come from `react-bootstrap-icons`, in the filled version.** A thin
|
|
450
|
+
outline disappears on a tint at small sizes. Where no filled twin exists (`X`,
|
|
451
|
+
`Check`, `Plus`, `Dash`) the heavy `*Lg` version is used, and `Caret*Fill`
|
|
452
|
+
instead of a chevron. Content icons (a category mark, a logo) always come from
|
|
453
|
+
outside as a `ReactNode` prop.
|
|
454
|
+
|
|
455
|
+
**Icon size is separate from text size.** The scale is its own set of values
|
|
456
|
+
(`$icon-xs` … `$icon-xl`: 14/16/18/20/24px); every box that carries an icon
|
|
457
|
+
takes its size from there.
|
|
458
|
+
|
|
459
|
+
**"Could not load" and "empty" are different states.** `DataTable` never draws
|
|
460
|
+
the empty message while `error` is set.
|
|
461
|
+
|
|
462
|
+
**A native element beats an imitation.** `<dialog>`, `<input type="range">`,
|
|
463
|
+
`<input type="radio">` are kept. The one exception is `<select>`: its list
|
|
464
|
+
cannot be styled and its mobile wheel looks like nothing else in the
|
|
465
|
+
application.
|
|
466
|
+
|
|
467
|
+
**A touch target is at least 44×44px** (WCAG 2.5.8). The visual box may be
|
|
468
|
+
smaller; an invisible overlay keeps the area.
|
|
469
|
+
|
|
470
|
+
**Motion uses the design durations** (`fast` 120ms, `base` 200ms, `slow`
|
|
471
|
+
320ms for a sheet) and every animation honours `prefers-reduced-motion`.
|
|
472
|
+
|
|
473
|
+
**The focus ring is `:focus-visible`**, 2px of cobalt with a 2px offset.
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
## Next.js App Router
|
|
478
|
+
|
|
479
|
+
The package draws the `'use client'` boundary **inside itself, per file**:
|
|
480
|
+
components without hooks (`Alert`, `Badge`, `Button`, `Card`, `Chip`,
|
|
481
|
+
`Divider`, `EmptyState`, `IconButton`, `Kbd`, `PageHeader`, `Panel`,
|
|
482
|
+
`Progress`, `SectionHeader`, `Skeleton`, `StatusDot`, `SummaryCard`,
|
|
483
|
+
`TextLink`, `Tile`) render as server components and send no JavaScript; the
|
|
484
|
+
interactive ones carry their own directive. No thin `Client*` wrappers are
|
|
485
|
+
needed, and `UIVariant` / `UISize` can be imported on the server.
|
|
486
|
+
|
|
487
|
+
```ts
|
|
488
|
+
// next.config.ts: the main entry is pure, so imports short-circuit to the component file.
|
|
489
|
+
const nextConfig = {
|
|
490
|
+
experimental: { optimizePackageImports: ['@handijit/ui'] },
|
|
491
|
+
};
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
```tsx
|
|
495
|
+
// app/layout.tsx, a server component
|
|
496
|
+
import '@handijit/design/tokens.css';
|
|
497
|
+
import '@handijit/design/fonts.css';
|
|
498
|
+
import '@handijit/ui/styles.css';
|
|
499
|
+
import '@handijit/ui/chat.css'; // only if /chat is used
|
|
500
|
+
import '@handijit/ui/charts.css'; // only if /charts is used
|
|
501
|
+
import { UiProvider, UiThemeScript } from '@handijit/ui';
|
|
502
|
+
import NextLink from 'next/link';
|
|
503
|
+
|
|
504
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
505
|
+
return (
|
|
506
|
+
<html lang="tr" suppressHydrationWarning>
|
|
507
|
+
<head>
|
|
508
|
+
<UiThemeScript />
|
|
509
|
+
</head>
|
|
510
|
+
<body>
|
|
511
|
+
<UiProvider linkComponent={NextLink}>{children}</UiProvider>
|
|
512
|
+
</body>
|
|
513
|
+
</html>
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
`suppressHydrationWarning`: the boot script adds an attribute to `<html>` that
|
|
519
|
+
the server did not write; the warning is silenced for that element only.
|
|
520
|
+
|
|
521
|
+
## Electron
|
|
522
|
+
|
|
523
|
+
The same three stylesheet imports in the renderer entry, and the boot script in
|
|
524
|
+
the HTML shell. With the usual strict policy of a packaged program, allow the
|
|
525
|
+
script by hash (`THEME_BOOT_SCRIPT_HASH`), and keep `style-src-attr
|
|
526
|
+
'unsafe-inline'` for the positioned components. With a mouse or a trackpad
|
|
527
|
+
`Select` and `Combobox` open dropdowns whatever the window width.
|
|
528
|
+
|
|
529
|
+
---
|
|
530
|
+
|
|
531
|
+
## Chat components: `@handijit/ui/chat`
|
|
532
|
+
|
|
533
|
+
A separate entry for chat and tool interfaces; it adds nothing to the main
|
|
534
|
+
bundle or to `styles.css`.
|
|
535
|
+
|
|
536
|
+
```tsx
|
|
537
|
+
import '@handijit/ui/styles.css';
|
|
538
|
+
import '@handijit/ui/chat.css'; // AFTER styles.css
|
|
539
|
+
|
|
540
|
+
import { ChatMessage, ChatThread, PromptInput } from '@handijit/ui/chat';
|
|
541
|
+
|
|
542
|
+
<ChatThread
|
|
543
|
+
isStreaming={isStreaming}
|
|
544
|
+
dock={
|
|
545
|
+
<PromptInput
|
|
546
|
+
value={draft}
|
|
547
|
+
onChange={setDraft}
|
|
548
|
+
onSubmit={send}
|
|
549
|
+
onStop={stop}
|
|
550
|
+
isBusy={isStreaming}
|
|
551
|
+
placeholder="Mesajınızı yazın…"
|
|
552
|
+
/>
|
|
553
|
+
}
|
|
554
|
+
>
|
|
555
|
+
{messages.map(message => (
|
|
556
|
+
<ChatMessage key={message.id} author={message.author}>
|
|
557
|
+
{message.content}
|
|
558
|
+
</ChatMessage>
|
|
559
|
+
))}
|
|
560
|
+
</ChatThread>;
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
Labels come from the same provider, under `labels.chat`:
|
|
564
|
+
|
|
565
|
+
```tsx
|
|
566
|
+
<UiProvider
|
|
567
|
+
labels={{
|
|
568
|
+
chat: {
|
|
569
|
+
thread: 'Sohbet',
|
|
570
|
+
send: 'Gönder',
|
|
571
|
+
stop: 'Durdur',
|
|
572
|
+
scrollToLatest: 'En yeniye in',
|
|
573
|
+
replyReady: 'Yanıt hazır',
|
|
574
|
+
messageActions: 'Mesaj eylemleri',
|
|
575
|
+
sources: 'Kaynaklar',
|
|
576
|
+
citation: index => `Kaynak ${index}`,
|
|
577
|
+
stderr: 'hata çıktısı',
|
|
578
|
+
toolStatus: { running: 'çalışıyor', ok: 'tamamlandı', error: 'hata', aborted: 'durduruldu', interrupted: 'kesildi' },
|
|
579
|
+
codeCopy: language => `${language} kodunu kopyala`,
|
|
580
|
+
codeCopied: 'Kod kopyalandı',
|
|
581
|
+
},
|
|
582
|
+
}}
|
|
583
|
+
>
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
`CodeBlock` highlights and formats the code itself, with no dependency:
|
|
587
|
+
|
|
588
|
+
```tsx
|
|
589
|
+
<CodeBlock language="json" code={JSON.stringify(payload)} />
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
JSON is re-indented with two spaces (values are kept as text: large numbers are
|
|
593
|
+
not rounded) and blank lines at the edges are dropped; other languages keep
|
|
594
|
+
their indentation. More than 30 languages are recognised; an unknown one is
|
|
595
|
+
drawn plain. The token colours are design tokens (keyword `primary-text`,
|
|
596
|
+
string `success-fg`, number `warning-fg`, type `highlight-text`), so they
|
|
597
|
+
follow the theme and stay inside the measured text pairs. For Shiki-grade
|
|
598
|
+
accuracy pass pre-highlighted HTML as `html` (its safety is yours).
|
|
599
|
+
|
|
600
|
+
Markdown parsing stays in the application: `Prose` is a typography container
|
|
601
|
+
only.
|
|
602
|
+
|
|
603
|
+
## Charts: `@handijit/ui/charts`
|
|
604
|
+
|
|
605
|
+
Ten SVG charts with no dependency (drawing, scales and statistics live in the
|
|
606
|
+
library).
|
|
607
|
+
|
|
608
|
+
```tsx
|
|
609
|
+
import '@handijit/ui/styles.css';
|
|
610
|
+
import '@handijit/ui/charts.css'; // AFTER styles.css
|
|
611
|
+
|
|
612
|
+
import { BarChart, LineChart, PieChart } from '@handijit/ui/charts';
|
|
613
|
+
|
|
614
|
+
<LineChart
|
|
615
|
+
label="Aylık gelir ve gider"
|
|
616
|
+
description="Gelir ekimde zirve yaptı"
|
|
617
|
+
xKey="month"
|
|
618
|
+
data={[
|
|
619
|
+
{ month: 'Oca', revenue: 120, cost: 90 },
|
|
620
|
+
{ month: 'Şub', revenue: 180, cost: null }, // null = no data: the line BREAKS
|
|
621
|
+
]}
|
|
622
|
+
series={[
|
|
623
|
+
{ key: 'revenue', label: 'Gelir' },
|
|
624
|
+
{ key: 'cost', label: 'Gider', format: value => `${value} ₺` },
|
|
625
|
+
]}
|
|
626
|
+
/>;
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
| Chart | When |
|
|
630
|
+
| ------------------------- | --------------------------------------------------------------- |
|
|
631
|
+
| `LineChart` · `AreaChart` | a trend over time; `AreaChart isStacked` for parts of a total |
|
|
632
|
+
| `BarChart` | comparing categories; `orientation="horizontal"` for long names |
|
|
633
|
+
| `ComposedChart` | bars and a line; a different unit on `axis: 'right'` |
|
|
634
|
+
| `PieChart` | at most six parts of a whole (`variant="donut"` by default) |
|
|
635
|
+
| `ScatterPlot` | the relation of two variables; a bubble with `size` |
|
|
636
|
+
| `Heatmap` | density on two categorical axes (day × hour) |
|
|
637
|
+
| `BoxPlot` · `Histogram` | distribution: comparing groups · the shape of one variable |
|
|
638
|
+
| `RadarChart` | a few series on one set of axes, all on the SAME scale |
|
|
639
|
+
|
|
640
|
+
Every chart is a single tab stop: arrows walk the items (each is announced),
|
|
641
|
+
`Home` / `End` go to the ends, `Escape` clears the highlight. A screen reader
|
|
642
|
+
also reads the chart as a hidden **data table**. Width is measured from the
|
|
643
|
+
container (or fixed with `width`); numbers are formatted with `labels.locale`.
|
|
644
|
+
Colours come from the data series of the design (`tone`: `chart-1` … `chart-6`,
|
|
645
|
+
`muted`).
|
|
646
|
+
|
|
647
|
+
## SCSS API: `@handijit/ui/scss`
|
|
648
|
+
|
|
649
|
+
Variables and mixins for the application's own stylesheets. The variables are
|
|
650
|
+
`var(--hd-…)` references, so the theme turns at run time; the module emits no
|
|
651
|
+
rules.
|
|
652
|
+
|
|
653
|
+
```scss
|
|
654
|
+
@use '@handijit/ui/scss' as ui;
|
|
655
|
+
|
|
656
|
+
.panel {
|
|
657
|
+
padding: ui.$space-4;
|
|
658
|
+
border: 1px solid ui.$border;
|
|
659
|
+
border-radius: ui.$radius-md;
|
|
660
|
+
|
|
661
|
+
@include ui.type(small);
|
|
662
|
+
@include ui.focus-ring;
|
|
663
|
+
|
|
664
|
+
@media (max-width: ui.$breakpoint-md) {
|
|
665
|
+
padding: ui.$space-3;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
**The values are custom properties, so SCSS arithmetic does not work.**
|
|
671
|
+
`$space-8 - $space-2` compiles to `var(--a)-var(--b)` without an error and the
|
|
672
|
+
browser drops the declaration. Write the calculation in `calc()`:
|
|
673
|
+
|
|
674
|
+
```scss
|
|
675
|
+
padding-inline-start: calc(#{ui.$space-8} - #{ui.$space-2});
|
|
676
|
+
margin-inline: calc(-1 * #{ui.$space-2});
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
Sass colour functions do not work either; mix in CSS:
|
|
680
|
+
`color-mix(in srgb, #{ui.$primary} 20%, transparent)`.
|
|
681
|
+
|
|
682
|
+
Next.js (Turbopack and webpack) resolves the package `exports`. For a compiler
|
|
683
|
+
that cannot, add `node_modules/@handijit/ui/build/scss` to `loadPaths` and
|
|
684
|
+
write `@use 'index' as ui`. An application that needs only the tokens can use
|
|
685
|
+
`@handijit/design/tokens.scss` directly.
|
|
686
|
+
|
|
687
|
+
---
|
|
688
|
+
|
|
689
|
+
## Development
|
|
690
|
+
|
|
691
|
+
```bash
|
|
692
|
+
nvm use # .nvmrc → 24
|
|
693
|
+
npm install
|
|
694
|
+
npm run verify # contrast → typecheck → lint → coverage → build → API → animations → size
|
|
695
|
+
npm run playground # component gallery → http://localhost:5273
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
| Command | |
|
|
699
|
+
| ------------------------ | ------------------------------------------------------------------------------------------- |
|
|
700
|
+
| `npm run build` | `build/`: main entry, `chat`, `charts` (ESM + CJS + `.d.ts` + CSS) and `build/scss/` |
|
|
701
|
+
| `npm run test` | Jest + Testing Library + `jest-axe` |
|
|
702
|
+
| `npm run test:coverage` | coverage gate over all of `src/`: lines 89 · statements 86 · functions 80 · branches 75 |
|
|
703
|
+
| `npm run check:contrast` | WCAG contrast of the pairs the components draw, both themes (240 pairs) |
|
|
704
|
+
| `npm run check:api` | public API guard: four entries, four baselines (main 163 · chat 30 · charts 22 · SCSS 225) |
|
|
705
|
+
| `npm run size` | bundle budget (`size-limit`) |
|
|
706
|
+
| `npm run exports` | writes the `exports` map of `package.json` (`check:exports` verifies; last step of `build`) |
|
|
707
|
+
| `npm run lint` | ESLint (TypeScript) + stylelint (SCSS) |
|
|
708
|
+
| `npm run format:check` | Prettier over `src`, `playground`, `__tests__` |
|
|
709
|
+
| `npm run typecheck` | `tsc --noEmit` |
|
|
710
|
+
| `npm run test:visual` | visual regression (Playwright); NOT part of `verify`, see below |
|
|
711
|
+
| `npm run test:device` | iOS (WebKit) and Android (Chromium) behaviour guards |
|
|
712
|
+
|
|
713
|
+
### What the guards protect
|
|
714
|
+
|
|
715
|
+
- **Design contract** (`__tests__/styles/design-contract.test.ts`): every
|
|
716
|
+
`--hd-*` name in the compiled stylesheets, the SCSS aliases and the
|
|
717
|
+
TypeScript sources exists in the installed `@handijit/design`; breakpoints
|
|
718
|
+
and layers match it; no stylesheet declares an `--hd-*` property or carries
|
|
719
|
+
a literal colour.
|
|
720
|
+
- **Colour footprint** (`colour-footprint.test.ts`): coral and turquoise tokens
|
|
721
|
+
are used only by the components on a justified allow-list.
|
|
722
|
+
- **Contrast**: text ≥ 4.5:1, icons and the focus ring ≥ 3:1, measured on the
|
|
723
|
+
values of the installed design package for every pair a component draws.
|
|
724
|
+
- **Accessibility scan** (`__tests__/components/a11y.test.tsx`): every exported
|
|
725
|
+
component in each meaningful state. A new component missing from the ledger
|
|
726
|
+
fails the test.
|
|
727
|
+
- **Keyboard contract**: the key matrix is in each component's JSDoc; its guard
|
|
728
|
+
is `keyboard.test.tsx`.
|
|
729
|
+
- **Control sizes** (`control-size.test.tsx`): `Input`, `DateField`,
|
|
730
|
+
`DateRange` and `Select` take their size from one mixin, and a text field
|
|
731
|
+
never drops below 16px on a narrow or touch screen.
|
|
732
|
+
- **Public API**: the exports of each entry are compared with a baseline. A
|
|
733
|
+
dropped name is **breaking** and surfaces as a build error at the consumer's
|
|
734
|
+
next install. For a deliberate change: `npm run build`, then
|
|
735
|
+
`node scripts/check-api.mjs --update`, and a line in the CHANGELOG.
|
|
736
|
+
- **Bundle size**: budgets in `.size-limit.js` (main entry 44 kB, `styles.css`
|
|
737
|
+
25 kB gzip). When `size-limit` turns red, measure what was added before
|
|
738
|
+
raising a limit.
|
|
739
|
+
- **Sub-entry boundary**: `chat` and `charts` import the main entry by PACKAGE
|
|
740
|
+
NAME only (`subentry-boundary.test.ts`); a relative path would bundle a
|
|
741
|
+
second copy of the provider context and the modal stack.
|
|
742
|
+
- **No fading with opacity**: any `opacity` other than `0` / `1` fails
|
|
743
|
+
(`passive-opacity.test.ts`); a disabled state is drawn with tokens.
|
|
744
|
+
- **Focus ring and motion scale**: stylelint rejects `outline` outside the
|
|
745
|
+
`focus-ring` mixin and raw durations in component SCSS.
|
|
746
|
+
|
|
747
|
+
### Device guards: `npm run test:device`
|
|
748
|
+
|
|
749
|
+
```bash
|
|
750
|
+
npm run test:device:install # WebKit and Chromium binaries (once)
|
|
751
|
+
npm run test:device # ios (iPhone 14 · WebKit) + android (Pixel 7 · Chromium)
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
The most expensive bugs of this repository were invisible on a desktop: a
|
|
755
|
+
collapsed sheet body, a bottom bar under the keyboard. They are layout and
|
|
756
|
+
paint bugs and can only be measured in a real layout engine. This run compares
|
|
757
|
+
numbers (height, overflow, focus, computed style), not pixels, so it needs no
|
|
758
|
+
reference files.
|
|
759
|
+
|
|
760
|
+
**Visual regression is not part of `verify`**: screenshots depend on the
|
|
761
|
+
platform (font rasterisation), and a reference made on macOS fails on the
|
|
762
|
+
ubuntu CI runner. References are stored per platform under
|
|
763
|
+
`__tests__/e2e/__screenshots__/{platform}/`.
|
|
764
|
+
|
|
765
|
+
> When refreshing references write `--update-snapshots=all`, not the bare
|
|
766
|
+
> flag: the bare flag writes only **missing** files and leaves mismatching ones
|
|
767
|
+
> in place while the run reports success.
|
|
768
|
+
|
|
769
|
+
### Releasing
|
|
770
|
+
|
|
771
|
+
Every push to `master` runs `.github/workflows/publish.yml`: it checks the formatting,
|
|
772
|
+
runs `npm run verify`, and publishes with the `NPM_ACCESS_TOKEN` repository
|
|
773
|
+
secret and npm provenance **when `package.json` carries a version that is not
|
|
774
|
+
on npm yet**; otherwise it skips. A published version gets a `vX.Y.Z` tag and a
|
|
775
|
+
GitHub Release whose notes are that version's section of `CHANGELOG.md`, so the
|
|
776
|
+
section must exist before the push.
|
|
777
|
+
|
|
778
|
+
## Design contract
|
|
779
|
+
|
|
780
|
+
Which element to use when, the surface ladder, colour roles, typography roles,
|
|
781
|
+
accessibility thresholds and the motion scale are in **`CLAUDE.md`**. That file
|
|
782
|
+
is normative for applications that use the library too. The visual language
|
|
783
|
+
itself (palette, type, logo) belongs to `@handijit/design`.
|
|
784
|
+
|
|
785
|
+
## License
|
|
786
|
+
|
|
787
|
+
MIT
|