├── .nvmrc ├── .github ├── CODEOWNERS ├── dependabot.yml └── workflows │ └── dependabot-prs.yaml ├── .husky ├── commit-msg └── pre-commit ├── .vscode ├── extensions.json └── settings.json ├── packages ├── storybook-addon-helpers │ ├── test │ │ ├── fixtures │ │ │ ├── no-stories.tsx │ │ │ ├── interfaces │ │ │ │ └── nested │ │ │ │ │ └── nested-types.ts │ │ │ └── components │ │ │ │ ├── external-props.ts │ │ │ │ └── imported-components.tsx │ │ └── index.node.test.ts │ ├── tsup.config.ts │ ├── CHANGELOG.md │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── src │ │ ├── plugin.ts │ │ ├── index.ts │ │ └── stories-indexer.ts │ └── LICENSE ├── radio │ ├── src │ │ ├── index.tsx │ │ └── radio-group-state.tsx │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ ├── examples │ │ ├── controlled.tsx │ │ ├── uncontrolled.tsx │ │ └── single-radio.tsx │ ├── radio.stories.tsx │ └── LICENSE ├── types │ ├── src │ │ ├── index.ts │ │ └── utility-types.d.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── CHANGELOG.md │ ├── vitest.config.ts │ ├── test │ │ └── utility-types.node.test.ts │ ├── README.md │ └── LICENSE ├── checkbox │ ├── src │ │ ├── index.tsx │ │ └── checkbox-group-state.tsx │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── examples │ │ ├── checkbox.tsx │ │ ├── checkbox-controlled.tsx │ │ ├── checkbox-group-controlled.tsx │ │ └── checkbox-group.tsx │ ├── vitest.config.ts │ ├── LICENSE │ └── checkbox.stories.tsx ├── pressable │ ├── src │ │ └── pressable.module.css │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ ├── examples │ │ ├── pressable-div.tsx │ │ ├── pressable-link-example.tsx │ │ └── pressable-custom.tsx │ ├── pressable.stories.tsx │ └── LICENSE ├── create-external-store │ ├── src │ │ └── index.ts │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── CHANGELOG.md │ ├── test │ │ ├── next.ts │ │ └── examples.browser.test.tsx │ ├── create-external-store.stories.tsx │ ├── examples │ │ └── create-store.tsx │ └── LICENSE ├── slots │ ├── src │ │ └── index.ts │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── test │ │ └── slots.visual.test.tsx │ ├── examples │ │ ├── button.tsx │ │ ├── slot-props.tsx │ │ ├── slot-function.tsx │ │ └── forward-ref.tsx │ └── LICENSE ├── forward │ ├── CHANGELOG.md │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── tsup.config.ts │ ├── examples │ │ ├── no-ref.tsx │ │ ├── already-wrapped.tsx │ │ ├── basic.tsx │ │ └── rest-params.tsx │ ├── forward.stories.tsx │ └── LICENSE ├── divider │ ├── examples │ │ ├── default-divider.tsx │ │ ├── vertical-style-override.tsx │ │ ├── vertical-div.tsx │ │ └── merge-classname.tsx │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── src │ │ └── styles.module.css │ ├── vitest.config.ts │ ├── divider.stories.tsx │ ├── LICENSE │ └── CHANGELOG.md ├── box │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── box.stories.tsx │ ├── CHANGELOG.md │ └── LICENSE ├── button │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ ├── examples │ │ ├── variants.tsx │ │ └── button.tsx │ ├── README.mdx │ ├── button.stories.tsx │ └── LICENSE ├── dismiss │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ ├── CHANGELOG.md │ ├── dismiss.stories.tsx │ ├── examples │ │ ├── custom-label.tsx │ │ └── basic.tsx │ └── LICENSE ├── error │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── CHANGELOG.md │ ├── error.stories.tsx │ ├── examples │ │ └── throws.tsx │ ├── LICENSE │ └── test │ │ └── examples.browser.test.tsx ├── heading │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── examples │ │ ├── heading.tsx │ │ ├── level.tsx │ │ ├── override.tsx │ │ └── provider.tsx │ ├── vitest.config.ts │ ├── test │ │ └── heading.browser.test.tsx │ └── LICENSE ├── icon │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── src │ │ └── icon.module.css │ ├── vitest.config.ts │ ├── examples │ │ └── icon.tsx │ ├── LICENSE │ └── icon.stories.tsx ├── input │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── examples │ │ ├── uncontrolled.tsx │ │ └── controlled.tsx │ ├── vitest.config.ts │ ├── CHANGELOG.md │ ├── input.stories.tsx │ ├── LICENSE │ └── test │ │ └── input.browser.test.tsx ├── listbox │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── src │ │ └── index.tsx │ ├── examples │ │ ├── basic-listbox.tsx │ │ ├── dynamic-collection.tsx │ │ ├── sections.tsx │ │ └── sections-dynamic.tsx │ └── LICENSE ├── overlay │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ ├── CHANGELOG.md │ ├── overlay.stories.tsx │ ├── LICENSE │ └── examples │ │ └── basic.tsx ├── portal │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ ├── CHANGELOG.md │ ├── examples │ │ ├── basic.tsx │ │ └── custom-container.tsx │ ├── portal.stories.tsx │ ├── test │ │ └── portal.node.test.tsx │ └── LICENSE ├── text │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── examples │ │ ├── text.tsx │ │ ├── as.tsx │ │ ├── align.tsx │ │ ├── max-lines.tsx │ │ └── wrap.tsx │ ├── vitest.config.ts │ ├── src │ │ └── index.module.css │ ├── test │ │ └── text.browser.test.tsx │ ├── text.stories.tsx │ └── LICENSE ├── use-props │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── examples │ │ ├── button-with-apply.tsx │ │ ├── button-with-apply-and-omit.tsx │ │ ├── button.tsx │ │ └── memo.tsx │ └── LICENSE ├── container │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── examples │ │ ├── basic.tsx │ │ ├── as.tsx │ │ ├── nested.tsx │ │ ├── empty.tsx │ │ └── building-block.tsx │ ├── vitest.config.ts │ ├── container.stories.tsx │ └── LICENSE ├── environment │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── environment.stories.tsx │ ├── LICENSE │ └── CHANGELOG.md ├── field-error │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── examples │ │ └── default.tsx │ ├── vitest.config.ts │ ├── field-error.stories.tsx │ ├── CHANGELOG.md │ ├── src │ │ └── index.tsx │ ├── test │ │ ├── examples.browser.test.tsx │ │ └── field-error.node.test.tsx │ ├── README.mdx │ └── LICENSE ├── focus-lock │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ ├── CHANGELOG.md │ ├── focus-lock.stories.tsx │ ├── LICENSE │ └── examples │ │ └── basic.tsx ├── illustration │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── examples │ │ └── rendering-svg.tsx │ ├── illustration.stories.tsx │ └── LICENSE ├── scroll-lock │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ ├── scroll-lock.stories.tsx │ ├── CHANGELOG.md │ ├── examples │ │ ├── hook.tsx │ │ └── basic.tsx │ └── LICENSE ├── svg-parser │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ ├── CHANGELOG.md │ ├── examples │ │ ├── basic.tsx │ │ └── custom-props.tsx │ └── LICENSE ├── to-attribute-value │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── CHANGELOG.md │ ├── test │ │ └── examples.browser.test.tsx │ ├── examples │ │ └── container.tsx │ └── LICENSE ├── use-data-attributes │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── CHANGELOG.md │ ├── data-attributes.stories.tsx │ ├── test │ │ └── examples.browser.test.tsx │ └── LICENSE ├── use-svg-sprite │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ ├── examples │ │ ├── basic.tsx │ │ └── multiple.tsx │ ├── CHANGELOG.md │ ├── svg-sprite.stories.tsx │ └── LICENSE ├── visually-hidden │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ ├── examples │ │ ├── default.tsx │ │ └── custom-element.tsx │ ├── CHANGELOG.md │ ├── visually-hidden.stories.tsx │ └── LICENSE └── internal-props │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── internal-props.stories.tsx │ ├── CHANGELOG.md │ ├── LICENSE │ └── tsup.config.ts ├── commitlint.config.ts ├── docs └── assets │ └── divider-children.png ├── playwright ├── index.tsx └── index.html ├── apps └── docs │ ├── tsconfig.json │ ├── .storybook │ ├── manager.ts │ └── addons │ │ └── why-did-you-render │ │ ├── index.ts │ │ └── why.tsx │ ├── vite.config.ts │ ├── tsconfig.node.json │ └── tsconfig.app.json ├── .npmrc ├── .changeset ├── config.json └── README.md ├── configs ├── tsup.config.mts └── tsconfig.json ├── .grit ├── no_anonymous_functions.grit ├── no_anonymous_single_param.grit ├── grit.yaml └── no_anonymous_function_expressions.grit ├── scripts └── test │ └── vitest.config.ts ├── SECURITY.md ├── LICENSE.md └── .gitignore /.nvmrc: -------------------------------------------------------------------------------- 1 | 23 -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @godaddy/bento 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | npx --no -- commitlint --edit "$1" 3 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["biomejs.biome"] 3 | } 4 | -------------------------------------------------------------------------------- /packages/storybook-addon-helpers/test/fixtures/no-stories.tsx: -------------------------------------------------------------------------------- 1 | export default {}; 2 | -------------------------------------------------------------------------------- /commitlint.config.ts: -------------------------------------------------------------------------------- 1 | export default { extends: ['@commitlint/config-conventional'] }; 2 | -------------------------------------------------------------------------------- /packages/radio/src/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './radio.tsx'; 2 | export * from './radio-group.tsx'; 3 | -------------------------------------------------------------------------------- /packages/types/src/index.ts: -------------------------------------------------------------------------------- 1 | export type { AnyObject, UnknownObject } from './utility-types.d.ts'; 2 | -------------------------------------------------------------------------------- /docs/assets/divider-children.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godaddy/bento/main/docs/assets/divider-children.png -------------------------------------------------------------------------------- /packages/checkbox/src/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './checkbox.tsx'; 2 | export * from './checkbox-group.tsx'; 3 | -------------------------------------------------------------------------------- /playwright/index.tsx: -------------------------------------------------------------------------------- 1 | // Import styles, initialize component theme here. 2 | // import '../src/common.css'; 3 | -------------------------------------------------------------------------------- /packages/pressable/src/pressable.module.css: -------------------------------------------------------------------------------- 1 | .pressable { 2 | display: inline-flex; 3 | appearance: none; 4 | } 5 | -------------------------------------------------------------------------------- /packages/create-external-store/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './create-external-store.ts'; 2 | export * from './observer.ts'; 3 | -------------------------------------------------------------------------------- /packages/slots/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './slots.tsx'; 2 | export * from './override.ts'; 3 | export * from './replace.ts'; 4 | export * from './contains.ts'; 5 | -------------------------------------------------------------------------------- /apps/docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /apps/docs/.storybook/manager.ts: -------------------------------------------------------------------------------- 1 | import { addons } from 'storybook/manager-api'; 2 | 3 | addons.setConfig({ 4 | sidebar: { 5 | collapsedRoots: ['architecture'] 6 | } 7 | }); 8 | -------------------------------------------------------------------------------- /packages/forward/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/forward 2 | 3 | ## 0.1.0 4 | 5 | ### Minor Changes 6 | 7 | - Forward ref support ([#59](https://github.com/godaddy/bento/pull/59) by @akazemier-godaddy) 8 | -------------------------------------------------------------------------------- /packages/forward/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["src"], 4 | "compilerOptions": { 5 | "outDir": "dist", 6 | "rootDir": "src" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/divider/examples/default-divider.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React from 'react'; 3 | import { Divider } from '@bento/divider'; 4 | 5 | export function Default() { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /packages/box/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mts'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/radio/src/radio-group-state.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { RadioGroupState } from 'react-stately'; 3 | 4 | export const RadioGroupStateContext = React.createContext(null); 5 | -------------------------------------------------------------------------------- /packages/types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src", "./test"], 4 | "compilerOptions": { 5 | "rootDir": "./", 6 | "declarationDir": "./dist" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/button/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/button/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/checkbox/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/checkbox/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/dismiss/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/dismiss/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/divider/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/divider/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/error/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mts'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.ts'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/heading/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/heading/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/icon/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/icon/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/input/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/input/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/listbox/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/overlay/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/overlay/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/portal/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/portal/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/radio/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/radio/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/slots/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mts'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.ts'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/text/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/text/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/types/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mts'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.ts'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/use-props/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.ts'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/box/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src", "./test", "./examples"], 4 | "compilerOptions": { 5 | "rootDir": "./", 6 | "declarationDir": "./dist" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/container/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/container/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/environment/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mts'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/field-error/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/field-error/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/focus-lock/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/focus-lock/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/illustration/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/pressable/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/pressable/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/scroll-lock/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/scroll-lock/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/svg-parser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/svg-parser/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mts'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.ts'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/checkbox/src/checkbox-group-state.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { CheckboxGroupState } from 'react-stately'; 3 | 4 | export const CheckboxGroupStateContext = React.createContext(null); 5 | -------------------------------------------------------------------------------- /packages/error/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src", "./test", "./examples"], 4 | "compilerOptions": { 5 | "rootDir": "./", 6 | "declarationDir": "./dist" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/listbox/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src", "./test", "./examples"], 4 | "compilerOptions": { 5 | "rootDir": "./", 6 | "declarationDir": "./dist" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/slots/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src", "./test", "./examples"], 4 | "compilerOptions": { 5 | "rootDir": "./", 6 | "declarationDir": "./dist" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/to-attribute-value/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mts'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.ts'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/use-data-attributes/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mts'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.ts'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/use-svg-sprite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/use-svg-sprite/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/visually-hidden/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src"], 4 | "compilerOptions": { 5 | "declarationDir": "./dist" 6 | }, 7 | "exclude": ["test", "examples"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/visually-hidden/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.tsx'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/create-external-store/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mts'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.ts'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/environment/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src", "./test", "./examples"], 4 | "compilerOptions": { 5 | "rootDir": "./", 6 | "declarationDir": "./dist" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/illustration/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src", "./test", "./examples"], 4 | "compilerOptions": { 5 | "rootDir": "./", 6 | "declarationDir": "./dist" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/input/examples/uncontrolled.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React from 'react'; 3 | import { Input } from '@bento/input'; 4 | 5 | export function UncontrolledInput() { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /packages/storybook-addon-helpers/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | ...shared, 6 | entry: ['src/index.ts'] 7 | }); 8 | -------------------------------------------------------------------------------- /packages/use-props/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src", "./test", "./examples"], 4 | "compilerOptions": { 5 | "rootDir": "./", 6 | "declarationDir": "./dist" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/internal-props/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src", "./test", "./examples"], 4 | "compilerOptions": { 5 | "rootDir": "./", 6 | "declarationDir": "./dist" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/to-attribute-value/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src", "./test", "./examples"], 4 | "compilerOptions": { 5 | "rootDir": "./", 6 | "declarationDir": "./dist" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/create-external-store/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src", "./test", "./examples"], 4 | "compilerOptions": { 5 | "rootDir": "./", 6 | "declarationDir": "./dist" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/types/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/types 2 | 3 | ## 0.1.0 4 | 5 | ### Minor Changes 6 | 7 | - chore: configure automated release workflow with changesets and GitHub Actions ([#168](https://github.com/godaddy/bento/pull/168) by @kbader-godaddy) 8 | -------------------------------------------------------------------------------- /packages/use-data-attributes/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../configs/tsconfig.json", 3 | "include": ["./src", "./test", "./examples"], 4 | "compilerOptions": { 5 | "rootDir": "./", 6 | "declarationDir": "./dist" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/text/examples/text.tsx: -------------------------------------------------------------------------------- 1 | import { Text, type TextProps } from '@bento/text'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function TextExample(args: TextProps) { 6 | return Hello, world!; 7 | } 8 | -------------------------------------------------------------------------------- /packages/divider/src/styles.module.css: -------------------------------------------------------------------------------- 1 | .divider { 2 | margin: 0; 3 | background-color: currentColor; 4 | border: none; 5 | width: 100%; 6 | height: 1px; 7 | 8 | &[aria-orientation="vertical"] { 9 | width: 1px; 10 | height: 100%; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/heading/examples/heading.tsx: -------------------------------------------------------------------------------- 1 | import { Heading, type HeadingProps } from '@bento/heading'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function HeadingExample(args: HeadingProps) { 6 | return Hello, world!; 7 | } 8 | -------------------------------------------------------------------------------- /packages/storybook-addon-helpers/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/storybook-addon-helpers 2 | 3 | ## 0.1.0 4 | 5 | ### Minor Changes 6 | 7 | - chore: configure automated release workflow with changesets and GitHub Actions ([#168](https://github.com/godaddy/bento/pull/168) by @kbader-godaddy) 8 | -------------------------------------------------------------------------------- /packages/storybook-addon-helpers/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../configs/tsconfig.json"], 3 | "include": ["./src", "./test"], 4 | "compilerOptions": { 5 | "rootDir": "./", 6 | "declarationDir": "./dist" 7 | }, 8 | "exclude": ["test/fixtures"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/divider/examples/vertical-style-override.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React from 'react'; 3 | import { Divider } from '@bento/divider'; 4 | 5 | export function VerticalStyleOverride() { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # Default registry for all packages 2 | registry=https://registry.npmjs.org/ 3 | 4 | # Allow saving dependencies with semver ranges (^, ~, etc.) 5 | save-exact=false 6 | 7 | # Use npm workspaces 8 | workspaces-update=true 9 | 10 | # Audit settings 11 | audit-level=moderate 12 | -------------------------------------------------------------------------------- /packages/container/examples/basic.tsx: -------------------------------------------------------------------------------- 1 | import { Container, type ContainerProps } from '@bento/container'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function BasicExample(args: ContainerProps) { 6 | return Hello from Container; 7 | } 8 | -------------------------------------------------------------------------------- /packages/field-error/examples/default.tsx: -------------------------------------------------------------------------------- 1 | import { FieldError, type FieldErrorProps } from '@bento/field-error'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function DefaultExample(args: FieldErrorProps) { 6 | return This field is required; 7 | } 8 | -------------------------------------------------------------------------------- /packages/text/examples/as.tsx: -------------------------------------------------------------------------------- 1 | import { Text, type TextProps } from '@bento/text'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function AsExample(args: TextProps) { 6 | return ( 7 | 8 | A scrolling marquee 9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /packages/box/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/error/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/heading/examples/level.tsx: -------------------------------------------------------------------------------- 1 | import { Heading, type HeadingProps } from '@bento/heading'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function LevelExample(args: HeadingProps) { 6 | return ( 7 | 8 | Hello, world! 9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /packages/input/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/storybook-addon-helpers/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/text/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/types/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/button/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/container/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/dismiss/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/divider/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/focus-lock/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/forward/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/heading/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/listbox/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/overlay/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/portal/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/pressable/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/svg-parser/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/text/examples/align.tsx: -------------------------------------------------------------------------------- 1 | import { Text, type TextProps } from '@bento/text'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function AlignExample(args: TextProps) { 6 | return ( 7 | 8 | Text is aligned to the center 9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /packages/use-props/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json", 3 | "changelog": "./changelog-config.js", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": ["docs"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/environment/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/illustration/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/internal-props/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/scroll-lock/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/use-svg-sprite/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/forward/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | import browserslistToEsbuild from 'browserslist-to-esbuild'; 3 | 4 | export default defineConfig({ 5 | entry: ['src/index.ts'], 6 | format: ['cjs', 'esm'], 7 | dts: true, 8 | sourcemap: true, 9 | clean: true, 10 | target: browserslistToEsbuild() 11 | }); 12 | -------------------------------------------------------------------------------- /packages/internal-props/internal-props.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getStory } from '@bento/storybook-addon-helpers'; 2 | import { Example as OverrideClassNameExample } from './examples/override-classname'; 3 | 4 | export default getMeta({ 5 | title: 'internal/internal-props' 6 | }); 7 | 8 | export const Demo = getStory(OverrideClassNameExample); 9 | -------------------------------------------------------------------------------- /packages/to-attribute-value/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/use-data-attributes/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser] 9 | } 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/container/examples/as.tsx: -------------------------------------------------------------------------------- 1 | import { Container, type ContainerProps } from '@bento/container'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function AsExample(args: ContainerProps) { 6 | return ( 7 | 8 | This is an article element 9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /packages/divider/examples/vertical-div.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React from 'react'; 3 | import { Divider } from '@bento/divider'; 4 | 5 | export function VerticalDiv() { 6 | return ( 7 |
8 | 9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /configs/tsup.config.mts: -------------------------------------------------------------------------------- 1 | import { type Options } from 'tsup'; 2 | import browserslistToEsbuild from 'browserslist-to-esbuild'; 3 | 4 | export const shared: Options = { 5 | format: ['esm', 'cjs'], 6 | sourcemap: true, 7 | clean: true, 8 | treeshake: true, 9 | loader: { '.css': 'copy' }, 10 | target: browserslistToEsbuild(), 11 | dts: true 12 | }; 13 | -------------------------------------------------------------------------------- /packages/button/examples/variants.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React, { type ComponentProps } from 'react'; 3 | import { Button } from '@bento/button'; 4 | 5 | export function ButtonVariantsExample(args: Partial>) { 6 | const { children = 'Click me!' } = args; 7 | 8 | return ; 9 | } 10 | -------------------------------------------------------------------------------- /playwright/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Testing Page 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/button/examples/button.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from '@bento/button'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function ButtonExample() { 6 | return ( 7 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /packages/checkbox/examples/checkbox.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React from 'react'; 3 | import { Checkbox } from '@bento/checkbox'; 4 | 5 | export function CheckboxExample(args: React.ComponentProps) { 6 | return ( 7 | 8 | Checkbox Label 9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /packages/checkbox/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | coverage: { 9 | exclude: ['src/index.tsx'] 10 | }, 11 | projects: [ssr, browser] 12 | } 13 | }) 14 | ); 15 | -------------------------------------------------------------------------------- /packages/radio/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | coverage: { 9 | exclude: ['src/index.tsx'] 10 | }, 11 | projects: [ssr, browser] 12 | } 13 | }) 14 | ); 15 | -------------------------------------------------------------------------------- /packages/slots/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | coverage: { 9 | exclude: ['src/index.ts'] 10 | }, 11 | projects: [ssr, browser] 12 | } 13 | }) 14 | ); 15 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Run lint-staged for code formatting/linting 4 | npx lint-staged 5 | 6 | # Run dependency checks to prevent circular deps and version mismatches 7 | echo "🔍 Checking dependencies..." 8 | npm run deps:check 9 | 10 | # Run package.json formatting 11 | echo "🔍 Checking package.json formatting..." 12 | npm run format:package 13 | 14 | echo "✅ All pre-commit checks passed!" 15 | -------------------------------------------------------------------------------- /packages/field-error/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | coverage: { 9 | exclude: ['src/index.tsx'] 10 | }, 11 | projects: [ssr, browser] 12 | } 13 | }) 14 | ); 15 | -------------------------------------------------------------------------------- /packages/pressable/examples/pressable-div.tsx: -------------------------------------------------------------------------------- 1 | import { Pressable } from '@bento/pressable'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function PressableDivExample() { 6 | return ( 7 | 12 |
Pressable Div
13 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /packages/visually-hidden/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | coverage: { 9 | exclude: ['src/index.tsx'] 10 | }, 11 | projects: [ssr, browser] 12 | } 13 | }) 14 | ); 15 | -------------------------------------------------------------------------------- /packages/create-external-store/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | coverage: { 9 | exclude: ['src/index.ts'] 10 | }, 11 | projects: [ssr, browser] 12 | } 13 | }) 14 | ); 15 | -------------------------------------------------------------------------------- /packages/types/src/utility-types.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents an object with string keys and any values. 3 | * 4 | * @public 5 | */ 6 | export type AnyObject = Record; 7 | 8 | /** 9 | * Represents an object with string keys and unknown values. 10 | * Safer alternative to AnyObject when the value types are not known. 11 | * 12 | * @public 13 | */ 14 | export type UnknownObject = Record; 15 | -------------------------------------------------------------------------------- /packages/focus-lock/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/focus-lock 2 | 3 | ## 0.0.2 4 | 5 | ### Patch Changes 6 | 7 |
8 | Updated dependencies 9 | 10 | - @bento/slots@0.3.0 11 | - @bento/use-props@0.2.1 12 |
13 | 14 | ## 0.0.1 15 | 16 | ### Patch Changes 17 | 18 |
19 | Updated dependencies 20 | 21 | - @bento/use-props@0.2.0 22 | - @bento/slots@0.2.0 23 |
24 | -------------------------------------------------------------------------------- /packages/pressable/examples/pressable-link-example.tsx: -------------------------------------------------------------------------------- 1 | import { Pressable } from '@bento/pressable'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function PressableLinkExample() { 6 | return ( 7 | 12 | Pressable Link 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /packages/error/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/error 2 | 3 | ## 0.1.1 4 | 5 | ### Patch Changes 6 | 7 | - Adds documentation to all packages; no API or functionality changes. ([#23](https://github.com/godaddy/bento/pull/23) by @kawikabader) 8 | 9 | ## 0.1.0 10 | 11 | ### Minor Changes 12 | 13 | - chore: configure automated release workflow with changesets and GitHub Actions ([#168](https://github.com/godaddy/bento/pull/168) by @kbader-godaddy) 14 | -------------------------------------------------------------------------------- /packages/field-error/field-error.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { FieldError } from './src/index.tsx'; 3 | import { DefaultExample } from './examples/default.tsx'; 4 | 5 | export default getMeta({ 6 | title: 'components/FieldError' 7 | }); 8 | 9 | export const Props = getComponentDocs(FieldError); 10 | 11 | export const Default = getStory(DefaultExample); 12 | -------------------------------------------------------------------------------- /packages/input/examples/controlled.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React, { useState } from 'react'; 3 | import { Input } from '@bento/input'; 4 | 5 | export function ControlledInput() { 6 | const [value, setValue] = useState(''); 7 | return ( 8 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /packages/slots/test/slots.visual.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { test, expect } from '@playwright/experimental-ct-react'; 3 | import { Button } from '../examples/button.tsx'; 4 | 5 | // TODO: Make these proper screenshot tests 6 | test('renders the app', async function renderApp({ mount }) { 7 | const component = await mount(); 8 | await expect(component).toHaveScreenshot('button.png'); 9 | }); 10 | -------------------------------------------------------------------------------- /packages/svg-parser/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/svg-parser 2 | 3 | ## 0.1.1 4 | 5 | ### Patch Changes 6 | 7 | - Adds documentation to all packages; no API or functionality changes. ([#23](https://github.com/godaddy/bento/pull/23) by @kawikabader) 8 | 9 | ## 0.1.0 10 | 11 | ### Minor Changes 12 | 13 | - chore: configure automated release workflow with changesets and GitHub Actions ([#168](https://github.com/godaddy/bento/pull/168) by @kbader-godaddy) 14 | -------------------------------------------------------------------------------- /packages/use-svg-sprite/examples/basic.tsx: -------------------------------------------------------------------------------- 1 | import { useSVGSprite } from '@bento/use-svg-sprite'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function BasicUsage() { 6 | const Icon = useSVGSprite( 7 | 'check', 8 | 9 | 10 | 11 | ); 12 | 13 | return
{Icon}
; 14 | } 15 | -------------------------------------------------------------------------------- /packages/icon/src/icon.module.css: -------------------------------------------------------------------------------- 1 | .icon { 2 | display: inline-flex; /* use the flexbox alignment model so it isn't affected by line-height */ 3 | flex-shrink: 0; /* ensures the icon doesn't shrink when placed within a flexbox */ 4 | align-items: center; /* center vertically */ 5 | justify-content: center; /* center horizontally */ 6 | height: 1lh; /* Use height as the relationship instead of character width (em) */ 7 | width: 1lh; /* Assume a square */ 8 | } 9 | -------------------------------------------------------------------------------- /packages/internal-props/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/internal-props 2 | 3 | ## 0.1.1 4 | 5 | ### Patch Changes 6 | 7 | - Adds documentation to all packages; no API or functionality changes. ([#23](https://github.com/godaddy/bento/pull/23) by @kawikabader) 8 | 9 | ## 0.1.0 10 | 11 | ### Minor Changes 12 | 13 | - chore: configure automated release workflow with changesets and GitHub Actions ([#168](https://github.com/godaddy/bento/pull/168) by @kbader-godaddy) 14 | -------------------------------------------------------------------------------- /packages/to-attribute-value/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/to-attribute-value 2 | 3 | ## 0.1.1 4 | 5 | ### Patch Changes 6 | 7 | - Adds documentation to all packages; no API or functionality changes. ([#23](https://github.com/godaddy/bento/pull/23) by @kawikabader) 8 | 9 | ## 0.1.0 10 | 11 | ### Minor Changes 12 | 13 | - chore: configure automated release workflow with changesets and GitHub Actions ([#168](https://github.com/godaddy/bento/pull/168) by @kbader-godaddy) 14 | -------------------------------------------------------------------------------- /apps/docs/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | plugins: [ 7 | // 8 | // The custom jsxImportSource option is required for the why-did-you-render 9 | // plugin to work. This ensure all JSX calls are correctly introspected. 10 | // 11 | react({ jsxImportSource: '@welldone-software/why-did-you-render' }) 12 | ] 13 | }); 14 | -------------------------------------------------------------------------------- /packages/create-external-store/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/create-external-store 2 | 3 | ## 0.1.1 4 | 5 | ### Patch Changes 6 | 7 | - Adds documentation to all packages; no API or functionality changes. ([#23](https://github.com/godaddy/bento/pull/23) by @kawikabader) 8 | 9 | ## 0.1.0 10 | 11 | ### Minor Changes 12 | 13 | - chore: configure automated release workflow with changesets and GitHub Actions ([#168](https://github.com/godaddy/bento/pull/168) by @kbader-godaddy) 14 | -------------------------------------------------------------------------------- /packages/container/examples/nested.tsx: -------------------------------------------------------------------------------- 1 | import { Container, type ContainerProps } from '@bento/container'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function NestedExample(args: ContainerProps) { 6 | return ( 7 | 8 | Header 9 | Main content 10 | Footer 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /packages/input/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/input 2 | 3 | ## 0.1.0 4 | 5 | ### Minor Changes 6 | 7 | - Adds @bento/input to the repo and to the @bento/checkbox and @bento/radio primitives. ([#54](https://github.com/godaddy/bento/pull/54) by @amarques-godaddy) 8 | 9 | ### Patch Changes 10 | 11 |
12 | Updated dependencies 13 | 14 | - @bento/slots@0.3.0 15 | - @bento/use-props@0.2.1 16 | - @bento/container@0.2.1 17 | - @bento/text@0.1.4 18 |
19 | -------------------------------------------------------------------------------- /packages/visually-hidden/examples/default.tsx: -------------------------------------------------------------------------------- 1 | import { VisuallyHidden, type VisuallyHiddenProps } from '@bento/visually-hidden'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function DefaultExample(args: VisuallyHiddenProps) { 6 | return ( 7 |
8 | 9 | 10 | 11 | Hit tab to focus the visually hidden button. 12 |
13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /packages/box/box.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getInterfaceDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { ContextExample } from './examples/namespace.tsx'; 3 | import { type EnvContext, type SlotsContext } from './src/index.ts'; 4 | 5 | export default getMeta({ 6 | title: 'internal/box' 7 | }); 8 | 9 | export const slots = getInterfaceDocs(); 10 | 11 | export const env = getInterfaceDocs>(); 12 | 13 | export const Namespace = getStory(ContextExample); 14 | -------------------------------------------------------------------------------- /packages/listbox/src/index.tsx: -------------------------------------------------------------------------------- 1 | export { Header, HeaderContext } from './header'; 2 | export { ListBoxItem } from './listbox-item'; 3 | export { ListBox, Collection } from './listbox'; 4 | export { ListBoxSection } from './listbox-section'; 5 | 6 | export type { HeaderProps } from './header'; 7 | export type { ListBoxSectionProps } from './listbox-section'; 8 | export type { ListBoxProps, ListBoxRenderProps } from './listbox'; 9 | export type { ListBoxItemProps, ListBoxItemRenderProps } from './listbox-item'; 10 | -------------------------------------------------------------------------------- /packages/visually-hidden/examples/custom-element.tsx: -------------------------------------------------------------------------------- 1 | import { VisuallyHidden, type VisuallyHiddenProps } from '@bento/visually-hidden'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function CustomElementExample(args: VisuallyHiddenProps) { 6 | return ( 7 |
8 | 9 | This content is hidden visually but accessible to screen readers 10 | 11 |

Visible content

12 |
13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /packages/heading/examples/override.tsx: -------------------------------------------------------------------------------- 1 | import { Heading, HeadingProvider, type HeadingProps } from '@bento/heading'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function HeadingOverrideExample(args: HeadingProps) { 6 | return ( 7 | 8 | Level 1 9 | 10 | Level 2 11 | Level 1 (overridden) 12 | 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) -------------------------------------------------------------------------------- /.grit/no_anonymous_functions.grit: -------------------------------------------------------------------------------- 1 | // Detect anonymous arrow functions with parentheses that use block statements (curly braces) 2 | // Only flag them if they do NOT reference 'this' in the function body 3 | `($args) => { $body }` where { 4 | not $body <: contains `this`, 5 | register_diagnostic( 6 | span = $args, 7 | message = "Anonymous arrow functions with block statements that don't reference 'this' should be converted to named function expressions for better debugging", 8 | severity = "error" 9 | ) 10 | } -------------------------------------------------------------------------------- /.grit/no_anonymous_single_param.grit: -------------------------------------------------------------------------------- 1 | // Detect single-parameter anonymous arrow functions that use block statements (curly braces) 2 | // Only flag them if they do NOT reference 'this' in the function body 3 | `$arg => { $body }` where { 4 | not $body <: contains `this`, 5 | register_diagnostic( 6 | span = $arg, 7 | message = "Anonymous arrow functions with block statements that don't reference 'this' should be converted to named function expressions for better debugging", 8 | severity = "error" 9 | ) 10 | } -------------------------------------------------------------------------------- /packages/storybook-addon-helpers/test/fixtures/interfaces/nested/nested-types.ts: -------------------------------------------------------------------------------- 1 | // Types in a nested directory to test relative imports 2 | 3 | export interface NestedInterface { 4 | /** Property from nested file */ 5 | nestedProp: string; 6 | 7 | /** 8 | * Another nested property 9 | * @default 42 10 | */ 11 | nestedNumber?: number; 12 | } 13 | 14 | export interface AnotherNestedInterface extends NestedInterface { 15 | /** Additional property in nested extended interface */ 16 | additionalProp: boolean; 17 | } 18 | -------------------------------------------------------------------------------- /packages/checkbox/examples/checkbox-controlled.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React, { useState } from 'react'; 3 | import { Checkbox } from '@bento/checkbox'; 4 | 5 | export function CheckboxControlledExample() { 6 | const [checked, setChecked] = useState(false); 7 | 8 | return ( 9 | 15 | Controlled Checkbox 16 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /packages/forward/examples/no-ref.tsx: -------------------------------------------------------------------------------- 1 | import { withForwardRef } from '@bento/forward'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | interface NoRefProps { 6 | children?: React.ReactNode; 7 | } 8 | 9 | /** 10 | * Example showing withForwardRef with a component that doesn't accept a ref. 11 | * The component is returned unchanged since it doesn't need ref forwarding. 12 | * 13 | * @public 14 | */ 15 | export const NoRef = withForwardRef(function NoRef(props) { 16 | return
{props.children}
; 17 | }); 18 | -------------------------------------------------------------------------------- /packages/slots/examples/button.tsx: -------------------------------------------------------------------------------- 1 | import { useProps } from '@bento/use-props'; 2 | import { withSlots } from '@bento/slots'; 3 | /* v8 ignore next */ 4 | import React from 'react'; 5 | 6 | /** 7 | * Button component for the slots example. 8 | * 9 | * @param {any} args - The component props. 10 | * @returns {JSX.Element} The rendered button. 11 | * @public 12 | */ 13 | export const Button = withSlots('SlotsButton', function ButtonComponent(args: any) { 14 | const { apply } = useProps(args); 15 | 16 | return ; 17 | }); 18 | -------------------------------------------------------------------------------- /packages/dismiss/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/dismiss 2 | 3 | ## 0.1.1 4 | 5 | ### Patch Changes 6 | 7 |
8 | Updated dependencies 9 | 10 | - @bento/slots@0.3.0 11 | - @bento/use-props@0.2.1 12 | - @bento/container@0.2.1 13 | - @bento/visually-hidden@0.1.1 14 |
15 | 16 | ## 0.1.0 17 | 18 | ### Minor Changes 19 | 20 | - Initial release of the Dismiss Primitive ([#40](https://github.com/godaddy/bento/pull/40) by @akazemier-godaddy) 21 | 22 | ### Patch Changes 23 | 24 |
25 | Updated dependencies 26 | 27 | - @bento/use-props@0.2.0 28 | - @bento/slots@0.2.0 29 | - @bento/visually-hidden@0.1.0 30 | - @bento/container@0.2.0 31 |
32 | -------------------------------------------------------------------------------- /packages/box/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/box 2 | 3 | ## 0.2.0 4 | 5 | ### Minor Changes 6 | 7 | - Introduces a new Slot component that enables flexible composition of child components by allowing content to be injected into predefined slots. ([#47](https://github.com/godaddy/bento/pull/47) by @akazemier-godaddy) 8 | 9 | ## 0.1.1 10 | 11 | ### Patch Changes 12 | 13 | - Adds documentation to all packages; no API or functionality changes. ([#23](https://github.com/godaddy/bento/pull/23) by @kawikabader) 14 | 15 | ## 0.1.0 16 | 17 | ### Minor Changes 18 | 19 | - chore: configure automated release workflow with changesets and GitHub Actions ([#168](https://github.com/godaddy/bento/pull/168) by @kbader-godaddy) 20 | -------------------------------------------------------------------------------- /configs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "lib": ["ESNext", "DOM"], 5 | "strict": true, 6 | "noUnusedLocals": true, 7 | "baseUrl": "./", 8 | "jsx": "preserve", 9 | "forceConsistentCasingInFileNames": true, 10 | "allowSyntheticDefaultImports": true, 11 | "moduleResolution": "bundler", 12 | "module": "ESNext", 13 | "declaration": true, 14 | "emitDeclarationOnly": true, 15 | "allowImportingTsExtensions": true, 16 | "allowJs": true, 17 | "esModuleInterop": true, 18 | "moduleDetection": "force", 19 | "skipLibCheck": true, 20 | "resolveJsonModule": true 21 | }, 22 | "exclude": ["node_modules", "dist"] 23 | } 24 | -------------------------------------------------------------------------------- /packages/checkbox/examples/checkbox-group-controlled.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React, { useState } from 'react'; 3 | import { Checkbox, CheckboxGroup } from '@bento/checkbox'; 4 | import { Text } from '@bento/text'; 5 | 6 | export function CheckboxGroupControlledExample() { 7 | const [selectedValues, setSelectedValues] = useState([]); 8 | 9 | return ( 10 | 11 | Checkbox Group 12 | Option 1 13 | Option 2 14 | Option 3 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /packages/text/examples/wrap.tsx: -------------------------------------------------------------------------------- 1 | import { Text, type TextProps } from '@bento/text'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function WrapExample(args: TextProps) { 6 | return ( 7 |
8 | 9 | Text is wrapped in a way that best balances the number of characters on each line, enhancing layout quality and 10 | legibility. Because counting characters and balancing them across multiple lines is computationally expensive, 11 | this value is only supported for blocks of text spanning a limited number of lines 12 | 13 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /apps/docs/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["vite.config.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /packages/svg-parser/examples/basic.tsx: -------------------------------------------------------------------------------- 1 | import { parser } from '@bento/svg-parser'; 2 | 3 | /** 4 | * Basic SVG parsing example 5 | * 6 | * This example demonstrates the simplest usage of the svg-parser. 7 | * It takes a basic SVG string and converts it to a React element. 8 | * 9 | * Usage: 10 | * ```tsx 11 | * import { BasicExample } from './examples/basic'; 12 | * 13 | * function App() { 14 | * return ; 15 | * } 16 | * ``` 17 | */ 18 | const basicSvg = ` 19 | 20 | 21 | 22 | `; 23 | 24 | export function BasicExample() { 25 | const parsedSvg = parser(basicSvg); 26 | return parsedSvg; 27 | } 28 | -------------------------------------------------------------------------------- /packages/use-props/examples/button-with-apply-and-omit.tsx: -------------------------------------------------------------------------------- 1 | import { useProps } from '@bento/use-props'; 2 | import { withSlots } from '@bento/slots'; 3 | /* v8 ignore next */ 4 | import React from 'react'; 5 | 6 | /** 7 | * Button component demonstrating apply and omit functionality. 8 | * 9 | * @param {Record} args - The component props. 10 | * @returns {JSX.Element} The rendered button element. 11 | * @public 12 | */ 13 | export const Button = withSlots('UsePropsApplyOmitButton', function BentoButton(args: Record) { 14 | const { props, apply } = useProps(args); 15 | 16 | return ; 17 | }); 18 | -------------------------------------------------------------------------------- /packages/listbox/examples/basic-listbox.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React from 'react'; 3 | import { ListBox, ListBoxItem } from '@bento/listbox'; 4 | import style from './listbox.module.css'; 5 | 6 | /** 7 | * Example component demonstrating basic ListBox usage. 8 | * 9 | * @param {any} args - The component props. 10 | * @returns {JSX.Element} The rendered ListBox with static items. 11 | * @public 12 | */ 13 | export function BasicListBoxExample(args: any) { 14 | return ( 15 | 16 | Chicken Teriyaki 17 | Salmon Bento 18 | Beef Bowl 19 | 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /packages/portal/portal.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { Portal as PortalComponent } from './src/index.tsx'; 3 | import { BasicExample } from './examples/basic.tsx'; 4 | import { CustomContainerExample } from './examples/custom-container.tsx'; 5 | import { PortalProviderExample } from './examples/portal-provider.tsx'; 6 | 7 | export default getMeta({ 8 | title: 'components/Portal' 9 | }); 10 | 11 | export const Props = getComponentDocs(PortalComponent); 12 | 13 | export const Basic = getStory(BasicExample); 14 | 15 | export const CustomContainer = getStory(CustomContainerExample); 16 | 17 | export const PortalProvider = getStory(PortalProviderExample); 18 | -------------------------------------------------------------------------------- /packages/use-data-attributes/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/use-data-attributes 2 | 3 | ## 0.1.1 4 | 5 | ### Patch Changes 6 | 7 | - Adds documentation to all packages; no API or functionality changes. ([#23](https://github.com/godaddy/bento/pull/23) by @kawikabader) 8 | 9 |
10 | Updated dependencies 11 | 12 | - @bento/to-attribute-value@0.1.1 13 |
14 | 15 | ## 0.1.0 16 | 17 | ### Minor Changes 18 | 19 | - chore: configure automated release workflow with changesets and GitHub Actions ([#168](https://github.com/godaddy/bento/pull/168) by @kbader-godaddy) 20 | 21 | ### Patch Changes 22 | 23 |
24 | Updated dependencies 25 | 26 | - @bento/to-attribute-value@0.1.0 27 |
28 | -------------------------------------------------------------------------------- /packages/field-error/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { withSlots } from '@bento/slots'; 3 | import { Text, type TextProps } from '@bento/text'; 4 | import { useProps } from '@bento/use-props'; 5 | import type { ValidationResult } from '@react-types/shared'; 6 | 7 | export interface FieldErrorProps extends TextProps, React.HTMLAttributes, Partial {} 8 | 9 | /** 10 | * The `FieldError` component is used to display error messages in form primitives, such as `RadioGroup` or `CheckboxGroup`. 11 | */ 12 | export const FieldError = withSlots('BentoFieldError', function FieldError(args: FieldErrorProps) { 13 | const { props } = useProps(args); 14 | return props.isInvalid ? : null; 15 | }); 16 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-prs.yaml: -------------------------------------------------------------------------------- 1 | name: Dependabot auto-approve 2 | on: 3 | pull_request: 4 | branches: 5 | - main 6 | 7 | permissions: 8 | pull-requests: write 9 | 10 | jobs: 11 | dependabot: 12 | runs-on: ubuntu-latest 13 | if: github.event.pull_request.user.login == 'dependabot[bot]' 14 | steps: 15 | - name: Dependabot metadata 16 | id: metadata 17 | uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b 18 | with: 19 | github-token: '${{ secrets.GITHUB_TOKEN }}' 20 | 21 | - name: Approve a PR 22 | run: gh pr review --approve "$PR_URL" 23 | env: 24 | PR_URL: ${{github.event.pull_request.html_url}} 25 | GH_TOKEN: ${{secrets.GITHUB_TOKEN}} 26 | -------------------------------------------------------------------------------- /packages/checkbox/examples/checkbox-group.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React from 'react'; 3 | import { Checkbox, CheckboxGroup } from '@bento/checkbox'; 4 | import { Text } from '@bento/text'; 5 | import { FieldError } from '@bento/field-error'; 6 | 7 | export function CheckboxGroupExample(args: React.ComponentProps) { 8 | return ( 9 | 10 | Checkbox Group 11 | Checkbox 1 12 | Checkbox 2 13 | Select your options 14 | This is an error message 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /packages/dismiss/dismiss.stories.tsx: -------------------------------------------------------------------------------- 1 | import { SlotCustomization as SlotCustomizationExample } from './examples/slot-customization.tsx'; 2 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 3 | import { CustomLabel as CustomLabelExample } from './examples/custom-label.tsx'; 4 | import { Dismiss as DismissComponent } from './src/index.tsx'; 5 | import { Basic as BasicExample } from './examples/basic.tsx'; 6 | 7 | export default getMeta({ 8 | title: 'components/Dismiss' 9 | }); 10 | 11 | export const Props = getComponentDocs(DismissComponent); 12 | 13 | export const Basic = getStory(BasicExample); 14 | 15 | export const CustomLabel = getStory(CustomLabelExample); 16 | 17 | export const SlotCustomization = getStory(SlotCustomizationExample); 18 | -------------------------------------------------------------------------------- /packages/pressable/pressable.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { Pressable } from './src/index.tsx'; 3 | import { PressableDivExample } from './examples/pressable-div.tsx'; 4 | import { PressableLinkExample } from './examples/pressable-link-example.tsx'; 5 | import { PressableCustomExample } from './examples/pressable-custom.tsx'; 6 | 7 | export default getMeta({ 8 | title: 'components/Pressable', 9 | component: Pressable 10 | }); 11 | 12 | export const Props = getComponentDocs(Pressable); 13 | 14 | export const PressableDiv = getStory(PressableDivExample); 15 | 16 | export const PressableLink = getStory(PressableLinkExample); 17 | 18 | export const PressableCustom = getStory(PressableCustomExample); 19 | -------------------------------------------------------------------------------- /packages/radio/examples/single-radio.tsx: -------------------------------------------------------------------------------- 1 | import { Radio, RadioGroup } from '@bento/radio'; 2 | import { Text } from '@bento/text'; 3 | /* v8 ignore next */ 4 | import React, { type ComponentProps } from 'react'; 5 | 6 | export function SingleRadioExample(props: { 7 | groupProps?: Partial>; 8 | radioProps?: Partial>; 9 | }) { 10 | return ( 11 | // Radios are always required to be in a group 12 | 13 | Favorite fruit (single radio) 14 | 15 | Apple 16 | 17 | This is the description 18 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /packages/use-props/examples/button.tsx: -------------------------------------------------------------------------------- 1 | import { useProps } from '@bento/use-props'; 2 | import { withSlots } from '@bento/slots'; 3 | /* v8 ignore next */ 4 | import React from 'react'; 5 | 6 | /** 7 | * Button component demonstrating render props usage. 8 | * 9 | * @param {Record} args - The component props. 10 | * @returns {JSX.Element} The rendered button or anchor element. 11 | * @public 12 | */ 13 | export const Button = withSlots('RenderPropsButton', function BentoButton(args: Record) { 14 | const { props, apply } = useProps(args); 15 | 16 | if (props.as) { 17 | return {props.children}; 18 | } 19 | 20 | return ; 21 | }); 22 | -------------------------------------------------------------------------------- /packages/input/input.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { Input } from './src/index.tsx'; 3 | import { BasicFormExample } from './examples/basic-form.tsx'; 4 | import { ControlledInput } from './examples/controlled.tsx'; 5 | import { UncontrolledInput } from './examples/uncontrolled.tsx'; 6 | import { FormExample } from './examples/form.tsx'; 7 | 8 | export default getMeta({ 9 | title: 'components/Input' 10 | }); 11 | 12 | export const Props = getComponentDocs(Input); 13 | 14 | export const BasicForm = getStory(BasicFormExample); 15 | 16 | export const Controlled = getStory(ControlledInput); 17 | 18 | export const Uncontrolled = getStory(UncontrolledInput); 19 | 20 | export const Form = getStory(FormExample); 21 | -------------------------------------------------------------------------------- /apps/docs/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "isolatedModules": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true 24 | }, 25 | "include": ["src"] 26 | } 27 | -------------------------------------------------------------------------------- /packages/button/README.mdx: -------------------------------------------------------------------------------- 1 | import { Meta, Story, ArgTypes, Controls, Source } from '@storybook/addon-docs/blocks'; 2 | import ButtonExample from './examples/button.tsx?raw'; 3 | import * as Stories from './button.stories.tsx'; 4 | 5 | 6 | 7 | # Button 8 | 9 | The `@bento/button` package exports the **Button** component, which is a complete button component built on top of the [**Pressable**](/docs/components-pressable--overview) primitive. 10 | 11 | ## Installation 12 | 13 | ```bash 14 | npm install --save @bento/button 15 | ``` 16 | 17 | ## Props 18 | 19 | The following properties are available to be used on the `Button` component: 20 | 21 | 22 | 23 | ## Examples 24 | 25 | 26 | -------------------------------------------------------------------------------- /packages/create-external-store/test/next.ts: -------------------------------------------------------------------------------- 1 | export interface NextFunction { 2 | (err?: Error): void; 3 | } 4 | 5 | /** 6 | * Wraps a given function in a callback that returns a promise. 7 | * 8 | * @param fn - The function to be wrapped. This function should accept a callback as its argument. 9 | * @returns A function that, when called, returns a promise which resolves when the original function's callback is called without an error, or rejects if the callback is called with an error. 10 | */ 11 | export function callback(fn: Function) { 12 | return function promisedACallback() { 13 | new Promise(function promise(resolve, reject) { 14 | fn(function next(err?: Error) { 15 | if (err) return reject(err); 16 | resolve(); 17 | }); 18 | }); 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /packages/pressable/examples/pressable-custom.tsx: -------------------------------------------------------------------------------- 1 | import { Pressable } from '@bento/pressable'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | // 6 | // to make a custom component pressable, you need to forward the ref to the 7 | // child element and pass the props to the child element 8 | // 9 | const CustomComponent = React.forwardRef(function CustomComponent(props, ref) { 10 | return ( 11 |
12 | Custom Component 13 |
14 | ); 15 | }); 16 | 17 | export function PressableCustomExample() { 18 | return ( 19 | 24 | 25 | 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /.grit/grit.yaml: -------------------------------------------------------------------------------- 1 | version: 0.0.0 2 | patterns: 3 | - name: no_anonymous_functions 4 | title: No Anonymous Functions 5 | description: "Detects anonymous arrow functions with parentheses that use block statements and don't reference 'this'" 6 | level: error 7 | tags: ["style", "debugging"] 8 | - name: no_anonymous_single_param 9 | title: No Anonymous Single Parameter Functions 10 | description: "Detects single-parameter anonymous arrow functions that use block statements and don't reference 'this'" 11 | level: error 12 | tags: ["style", "debugging"] 13 | - name: no_anonymous_function_expressions 14 | title: No Anonymous Function Expressions 15 | description: "Detects traditional anonymous function expressions" 16 | level: error 17 | tags: ["style", "debugging"] -------------------------------------------------------------------------------- /packages/use-data-attributes/data-attributes.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getStory } from '@bento/storybook-addon-helpers'; 2 | import { Container } from './examples/container.tsx'; 3 | 4 | export default getMeta({ 5 | title: 'hooks/use-data-attributes' 6 | }); 7 | 8 | export const useDataAttributesProps = { 9 | tags: ['!dev', 'stable'], 10 | argTypes: { 11 | props: { 12 | description: 'The object that needs to be introduced as data- attributes', 13 | type: 'object', 14 | required: true 15 | } 16 | } 17 | }; 18 | 19 | export const Demo = getStory(Container, { 20 | args: { 21 | example: ['1', '2', 'foo-bar'], 22 | focused: true, 23 | transform: { rotate: '45deg' }, 24 | children: 'Inspect my DOM to see the resulting data- attributes' 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /packages/container/container.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { Container as ContainerComponent } from './src/index.tsx'; 3 | import { BasicExample } from './examples/basic.tsx'; 4 | import { AsExample } from './examples/as.tsx'; 5 | import { BuildingBlockExample } from './examples/building-block.tsx'; 6 | import { NestedExample } from './examples/nested.tsx'; 7 | 8 | export default getMeta({ 9 | title: 'components/Container' 10 | }); 11 | 12 | export const Props = getComponentDocs(ContainerComponent); 13 | 14 | export const Basic = getStory(BasicExample); 15 | 16 | export const As = getStory(AsExample); 17 | 18 | export const BuildingBlock = getStory(BuildingBlockExample); 19 | 20 | export const Nested = getStory(NestedExample); 21 | -------------------------------------------------------------------------------- /packages/listbox/examples/dynamic-collection.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React from 'react'; 3 | import { ListBox, ListBoxItem } from '@bento/listbox'; 4 | import style from './listbox.module.css'; 5 | 6 | /** 7 | * Example component demonstrating ListBox with dynamic collections. 8 | * 9 | * @param {any} args - The component props including items array. 10 | * @returns {JSX.Element} The rendered ListBox with dynamic items. 11 | * @public 12 | */ 13 | export function DynamicCollectionExample({ items, ...args }: any) { 14 | return ( 15 | 16 | {(item: any) => ( 17 | 18 | {item.name} 19 | 20 | )} 21 | 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /packages/forward/examples/basic.tsx: -------------------------------------------------------------------------------- 1 | import { withForwardRef } from '@bento/forward'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | interface BasicExampleProps { 6 | children?: React.ReactNode; 7 | className?: string; 8 | } 9 | 10 | /** 11 | * Basic example showing withForwardRef with a component that has 2 parameters. 12 | * In React 18, this will be automatically wrapped with forwardRef. 13 | * In React 19, it returns the component unchanged (refs are passed as props). 14 | * 15 | * @public 16 | */ 17 | export const BasicExample = withForwardRef(function BasicExample( 18 | props, 19 | ref: React.ForwardedRef 20 | ) { 21 | return ( 22 |
23 | {props.children} 24 |
25 | ); 26 | }); 27 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting Security Issues 2 | 3 | We take security very seriously at GoDaddy. We appreciate your efforts to 4 | responsibly disclose your findings, and will make every effort to acknowledge 5 | your contributions. 6 | 7 | ## Where should I report security issues? 8 | 9 | In order to give the community time to respond and upgrade, we strongly urge you to 10 | report all security issues privately. 11 | 12 | To report a security issue in one of our Open Source projects email us directly 13 | at and include the word "SECURITY" in the subject line. 14 | 15 | This mail is delivered to our Open Source Security team. 16 | 17 | After the initial reply to your report, the team will keep you informed of the 18 | progress being made towards a fix and announcement, and may ask for additional 19 | information or guidance. 20 | -------------------------------------------------------------------------------- /packages/create-external-store/create-external-store.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getInterfaceDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { CreateStore } from './examples/create-store.tsx'; 3 | import { Icon } from './examples/icon.tsx'; 4 | import { type Store as StoreType } from './src/create-external-store.ts'; 5 | 6 | export default getMeta({ 7 | title: 'utility/create-external-store' 8 | }); 9 | 10 | export const api = getInterfaceDocs(); 11 | 12 | export const Icons = getStory(Icon, { 13 | args: { 14 | icon: 'octopus-sausages', 15 | fill: 'salmon' 16 | } 17 | }); 18 | 19 | export const Store = getStory(CreateStore, { 20 | args: { 21 | myArray: [1, 2, 3], 22 | aObject: { foo: 'bar' }, 23 | someBoolean: true, 24 | more: 'hello world', 25 | data: 1337 26 | } 27 | }); 28 | -------------------------------------------------------------------------------- /packages/slots/examples/slot-props.tsx: -------------------------------------------------------------------------------- 1 | import { Nested } from './nested.tsx'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | // 6 | // We define the slots object outside of the component scope to avoid 7 | // introducing a new object reference on each render which would cause 8 | // the Nested component to re-render unnecessarily. 9 | // 10 | const slots = { 11 | 'example-container.button': { 12 | style: { 13 | background: 'red', 14 | border: '2px solid black' 15 | }, 16 | onClick: () => console.log('Button clicked!') 17 | } 18 | }; 19 | 20 | /** 21 | * SlotProps component demonstrating how to pass slot-specific props. 22 | * 23 | * @returns {JSX.Element} The rendered Nested component with slot props. 24 | * @public 25 | */ 26 | export function SlotProps() { 27 | return ; 28 | } 29 | -------------------------------------------------------------------------------- /packages/portal/examples/custom-container.tsx: -------------------------------------------------------------------------------- 1 | import { Portal } from '@bento/portal'; 2 | import { Container } from '@bento/container'; 3 | import { Text } from '@bento/text'; 4 | /* v8 ignore next */ 5 | import React, { useState, useEffect, useRef } from 'react'; 6 | 7 | export function CustomContainerExample() { 8 | const [mounted, setMounted] = useState(false); 9 | const containerRef = useRef(null); 10 | 11 | useEffect(function mount() { 12 | setMounted(true); 13 | }, []); 14 | 15 | return ( 16 | <> 17 |
18 | 19 | 20 | Custom container content 21 | 22 | 23 | 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /packages/text/text.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { Text as TextComponent } from './src/index.tsx'; 3 | import { TextExample } from './examples/text.tsx'; 4 | import { AlignExample } from './examples/align.tsx'; 5 | import { AsExample } from './examples/as.tsx'; 6 | import { MaxLinesExample } from './examples/max-lines.tsx'; 7 | import { WrapExample } from './examples/wrap.tsx'; 8 | 9 | export default getMeta({ 10 | title: 'components/Text' 11 | }); 12 | 13 | export const Props = getComponentDocs(TextComponent); 14 | 15 | export const Text = getStory(TextExample); 16 | 17 | export const Align = getStory(AlignExample); 18 | 19 | export const As = getStory(AsExample); 20 | 21 | export const MaxLines = getStory(MaxLinesExample); 22 | 23 | export const Wrap = getStory(WrapExample); 24 | -------------------------------------------------------------------------------- /packages/use-svg-sprite/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/use-svg-sprite 2 | 3 | ## 0.1.2 4 | 5 | ### Patch Changes 6 | 7 |
8 | Updated dependencies 9 | 10 | - @bento/box@0.2.0 11 |
12 | 13 | ## 0.1.1 14 | 15 | ### Patch Changes 16 | 17 | - Adds documentation to all packages; no API or functionality changes. ([#23](https://github.com/godaddy/bento/pull/23) by @kawikabader) 18 | 19 |
20 | Updated dependencies 21 | 22 | - @bento/box@0.1.1 23 |
24 | 25 | ## 0.1.0 26 | 27 | ### Minor Changes 28 | 29 | - chore: configure automated release workflow with changesets and GitHub Actions ([#168](https://github.com/godaddy/bento/pull/168) by @kbader-godaddy) 30 | 31 | ### Patch Changes 32 | 33 |
34 | Updated dependencies 35 | 36 | - @bento/box@0.1.0 37 |
38 | -------------------------------------------------------------------------------- /packages/icon/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import sharedConfig, { ssr, browser } from '../../configs/vitest.config.mts'; 2 | import { defineConfig, mergeConfig } from 'vitest/config'; 3 | 4 | export default mergeConfig( 5 | sharedConfig, 6 | defineConfig({ 7 | test: { 8 | projects: [ssr, browser], 9 | coverage: { 10 | exclude: ['src/index.ts'], 11 | thresholds: { 12 | // 13 | // Lower the coverage thresholds for the icon package to 90% because 14 | // the coverage reporter is including `import` statements and 15 | // `empty lines` as part of the coverage check. 16 | // 17 | 'src/**.{ts,tsx}': { 18 | statements: 90, 19 | functions: 90, 20 | branches: 90, 21 | lines: 90 22 | } 23 | } 24 | } 25 | } 26 | }) 27 | ); 28 | -------------------------------------------------------------------------------- /packages/divider/divider.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { MergeClassName } from './examples/merge-classname.tsx'; 3 | import { Divider as DividerComponent } from './src/index.tsx'; 4 | import { Default } from './examples/default-divider.tsx'; 5 | import { VerticalStyleOverride } from './examples/vertical-style-override.tsx'; 6 | import { VerticalDiv } from './examples/vertical-div.tsx'; 7 | 8 | export default getMeta({ 9 | title: 'components/Divider' 10 | }); 11 | 12 | export const Props = getComponentDocs(DividerComponent); 13 | 14 | export const Divider = getStory(Default); 15 | 16 | export const VerticalDivider = getStory(VerticalStyleOverride); 17 | 18 | export const VerticalDividerInADiv = getStory(VerticalDiv); 19 | 20 | export const MergeClassNameExample = getStory(MergeClassName); 21 | -------------------------------------------------------------------------------- /packages/use-svg-sprite/examples/multiple.tsx: -------------------------------------------------------------------------------- 1 | import { useSVGSprite } from '@bento/use-svg-sprite'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function MultipleIcons() { 6 | const Check = useSVGSprite( 7 | 'check', 8 | 9 | 10 | 11 | ); 12 | 13 | const Alert = useSVGSprite( 14 | 'alert', 15 | 16 | 17 | 18 | 19 | 20 | ); 21 | 22 | return ( 23 |
24 | {Check} 25 | {Alert} 26 |
27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /packages/focus-lock/focus-lock.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { FocusLock } from './src/index.tsx'; 3 | import { BasicExample } from './examples/basic.tsx'; 4 | import { NestedExample } from './examples/nested.tsx'; 5 | import { OverlayExample } from './examples/overlay.tsx'; 6 | import { SelectExample } from './examples/select.tsx'; 7 | import { FormExample } from './examples/form.tsx'; 8 | 9 | export default getMeta({ 10 | title: 'components/FocusLock' 11 | }); 12 | 13 | export const Props = getComponentDocs(FocusLock); 14 | 15 | export const Basic = getStory(BasicExample); 16 | 17 | export const Nested = getStory(NestedExample); 18 | 19 | export const Overlay = getStory(OverlayExample); 20 | 21 | export const Select = getStory(SelectExample); 22 | 23 | export const Form = getStory(FormExample); 24 | -------------------------------------------------------------------------------- /packages/button/button.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory, getVariants } from '@bento/storybook-addon-helpers'; 2 | import { Button } from './src/index.tsx'; 3 | import { ButtonExample } from './examples/button.tsx'; 4 | import { ButtonVariantsExample } from './examples/variants.tsx'; 5 | 6 | export default getMeta({ 7 | title: 'components/Button' 8 | }); 9 | 10 | export const Props = getComponentDocs(Button); 11 | 12 | export const Default = getStory(ButtonExample); 13 | 14 | export const Styles = getVariants(ButtonVariantsExample, { 15 | primary: { 16 | args: { 17 | onPress: () => console.log('primary pressed!'), 18 | style: { backgroundColor: 'red', color: 'white' } 19 | } 20 | }, 21 | secondary: { 22 | args: { 23 | children: 'Secondary!', 24 | style: { backgroundColor: 'blue', color: 'white' } 25 | } 26 | } 27 | }); 28 | -------------------------------------------------------------------------------- /packages/forward/examples/rest-params.tsx: -------------------------------------------------------------------------------- 1 | import { withForwardRef } from '@bento/forward'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | interface RestParamsProps { 6 | children?: React.ReactNode; 7 | className?: string; 8 | } 9 | 10 | /** 11 | * Example showing withForwardRef with rest parameters (...args). 12 | * This pattern is useful for the future useProps(...args) API. 13 | * In React 18, this will be automatically wrapped with forwardRef. 14 | * 15 | * @public 16 | */ 17 | export const RestParams = withForwardRef(function RestParams(...args: any[]) { 18 | // Future API pattern: const { props, ref } = useProps(args, state); 19 | // For now, just demonstrate the pattern 20 | const [props, ref] = args; 21 | 22 | return ( 23 |
24 | {props?.children} 25 |
26 | ); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/illustration/examples/rendering-svg.tsx: -------------------------------------------------------------------------------- 1 | import { Illustration } from '@bento/illustration'; 2 | import { type UnknownObject } from '@bento/types'; 3 | /* v8 ignore next */ 4 | import React from 'react'; 5 | 6 | /** 7 | * Example component demonstrating SVG rendering with Illustration. 8 | * 9 | * @param {UnknownObject} args - The component props. 10 | * @returns {JSX.Element} The rendered component with SVG illustration. 11 | * @public 12 | */ 13 | export function RenderingSvg(args: UnknownObject) { 14 | return ( 15 | 16 | 17 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /packages/slots/examples/slot-function.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React from 'react'; 3 | import { Nested } from './nested.tsx'; 4 | 5 | // 6 | // We define the slots object outside of the component scope to avoid 7 | // introducing a new object reference on each render which would cause 8 | // the Nested component to re-render unnecessarily. 9 | // 10 | const slots = { 11 | 'example-container.label': function example({ props }: { props: Record }) { 12 | return ( 13 | 16 | ); 17 | } 18 | }; 19 | 20 | /** 21 | * SlotFunction component demonstrating how to pass a slot as a function. 22 | * 23 | * @returns {JSX.Element} The rendered Nested component with a slot function. 24 | * @public 25 | */ 26 | export function SlotFunction() { 27 | return ; 28 | } 29 | -------------------------------------------------------------------------------- /packages/icon/examples/icon.tsx: -------------------------------------------------------------------------------- 1 | import { Icon, set } from '@bento/icon'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | // 6 | // Uses the exposed `set` method to introduce the icons and their content to 7 | // the icon store. 8 | // 9 | set({ 10 | play: ( 11 | 12 | 13 | 14 | ) 15 | }); 16 | 17 | /** 18 | * Example component demonstrating basic icon usage. 19 | * 20 | * @param {any} args - The component props. 21 | * @returns {JSX.Element} The rendered icon with description. 22 | * @public 23 | */ 24 | export function Example(args: any) { 25 | return ( 26 | <> 27 | 28 |

29 | A simple play icon, with an embed title element for a11y. 30 |

31 | 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /packages/illustration/illustration.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { RotateSVG } from './examples/rotate-illustration.tsx'; 3 | import { RenderingSvg } from './examples/rendering-svg.tsx'; 4 | import { Illustration } from './src/index.tsx'; 5 | 6 | export default getMeta({ 7 | title: 'components/Illustration', 8 | component: Illustration, 9 | argTypes: { 10 | flip: { 11 | options: ['none', 'horizontal', 'vertical'], 12 | control: { type: 'radio' } 13 | }, 14 | rotate: { 15 | options: [0, 90, 180, 270], 16 | control: { type: 'radio' } 17 | } 18 | } 19 | }); 20 | 21 | export const Props = getComponentDocs(Illustration); 22 | 23 | export const Demo = getStory(RenderingSvg, { 24 | args: { 25 | title: 'A play button' 26 | } 27 | }); 28 | 29 | export const Rotate = getStory(RotateSVG); 30 | -------------------------------------------------------------------------------- /packages/scroll-lock/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/scroll-lock 2 | 3 | ## 0.1.2 4 | 5 | ### Patch Changes 6 | 7 | - Fixed TypeScript inference error in setAttribute call ([#80](https://github.com/godaddy/bento/pull/80) by @kbader-godaddy) 8 | 9 |
10 | Updated dependencies 11 | 12 | - @bento/use-props@0.2.2 13 |
14 | 15 | ## 0.1.1 16 | 17 | ### Patch Changes 18 | 19 |
20 | Updated dependencies 21 | 22 | - @bento/slots@0.3.0 23 | - @bento/use-props@0.2.1 24 |
25 | 26 | ## 0.1.0 27 | 28 | ### Minor Changes 29 | 30 | - Initial release of the ScrollLock component and hook ([#46](https://github.com/godaddy/bento/pull/46) by @akazemier-godaddy) 31 | 32 | ### Patch Changes 33 | 34 |
35 | Updated dependencies 36 | 37 | - @bento/use-props@0.2.0 38 | - @bento/slots@0.2.0 39 | - @bento/box@0.2.0 40 |
41 | -------------------------------------------------------------------------------- /packages/storybook-addon-helpers/test/index.node.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, vi } from 'vitest'; 2 | import { experimental_indexers, viteFinal } from '../src/index.ts'; 3 | import { generateCSFPlugin } from '../src/plugin.ts'; 4 | 5 | describe('index.ts', function coverageTests() { 6 | it('should load index.ts and plugin.ts without throwing', async function testCoverage() { 7 | // index 8 | (experimental_indexers as any)(); 9 | (experimental_indexers as any)([]); 10 | (viteFinal as any)({}); 11 | 12 | // plugin 13 | vi.mock('../src/csf-transformer.ts', () => ({ 14 | csfTransformer: vi.fn().mockReturnValue('mocked-code') 15 | })); 16 | const mockContext = { addWatchFile: vi.fn() }; 17 | const plugin = generateCSFPlugin(/\.stories\.tsx$/); 18 | await (plugin.load as any)?.call(mockContext, 'test.stories.tsx'); 19 | 20 | vi.restoreAllMocks(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/use-props/examples/memo.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React, { useCallback } from 'react'; 3 | import { type UnknownObject } from '@bento/types'; 4 | import { Button } from './button.tsx'; 5 | 6 | /** 7 | * Memo component demonstrating class name composition with useCallback. 8 | * 9 | * @param {UnknownObject} props - The component props. 10 | * @returns {JSX.Element} The rendered button with composed class names. 11 | * @public 12 | */ 13 | export function Memo(props: UnknownObject) { 14 | const className = useCallback( 15 | function renderProps({ original }: { original: string }) { 16 | return [original, 'my-className', props.className].filter(Boolean).join(' '); 17 | }, 18 | [props.className] 19 | ); 20 | 21 | return ( 22 | 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /packages/to-attribute-value/test/examples.browser.test.tsx: -------------------------------------------------------------------------------- 1 | import { Container } from '../examples/container.tsx'; 2 | import { render } from 'vitest-browser-react'; 3 | import { describe, it } from 'vitest'; 4 | import assume from 'assume'; 5 | import React from 'react'; 6 | 7 | describe('@bento/to-attribute-value examples', function bento() { 8 | describe('Container', function container() { 9 | it('should render the Container component', function test() { 10 | const { container } = render( 11 | 12 | ); 13 | const result = container.innerHTML; 14 | 15 | assume(result).includes('prop "example" is formatted as "1 2 foo-bar"'); 16 | assume(result).includes('prop "focused" is formatted as "true"'); 17 | assume(result).includes('prop "transform" is formatted as "rotate(45deg)"'); 18 | }); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/field-error/test/examples.browser.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from 'vitest-browser-react'; 3 | import { describe, it } from 'vitest'; 4 | import assume from 'assume'; 5 | import { DefaultExample } from '../examples/default.tsx'; 6 | 7 | describe('@bento/field-error examples', function bento() { 8 | describe('FieldError', function fieldErrorExample() { 9 | it('renders the default example', function rendersDefault() { 10 | const { container } = render(); 11 | const result = container.innerHTML; 12 | 13 | assume(result).includes('This field is required'); 14 | }); 15 | 16 | it('does not render when isInvalid is false', function doesNotRenderWhenInvalid() { 17 | const { container } = render(); 18 | const result = container.innerHTML; 19 | 20 | assume(result).equals(''); 21 | }); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/types/test/utility-types.node.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expectTypeOf, it } from 'vitest'; 2 | import type { AnyObject, UnknownObject } from '../src/utility-types.js'; 3 | 4 | describe('Utility types', function utilities() { 5 | it('should enforce type safety for UnknownObject', function unknown() { 6 | const unknownObj: UnknownObject = { key: 123 }; 7 | 8 | expectTypeOf(unknownObj).toBeObject(); 9 | expectTypeOf(unknownObj.key).toBeUnknown(); 10 | expectTypeOf(unknownObj.key).not.toBeNumber(); 11 | expectTypeOf(unknownObj.nonexistentKey).toBeUnknown(); 12 | expectTypeOf(unknownObj.nonexistentKey).not.toBeNumber(); 13 | }); 14 | 15 | it('should not enforce type safety for AnyObject', function any() { 16 | const anyObj: AnyObject = { key: 123 }; 17 | 18 | expectTypeOf(anyObj).toBeObject(); 19 | expectTypeOf(anyObj.key).toBeAny(); 20 | expectTypeOf(anyObj.nonexistentKey).toBeAny(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/to-attribute-value/examples/container.tsx: -------------------------------------------------------------------------------- 1 | import { stringify } from '@bento/to-attribute-value'; 2 | import { withSlots } from '@bento/slots'; 3 | /* c8 ignore next */ 4 | import React from 'react'; 5 | 6 | interface Example { 7 | [key: string]: any; 8 | } 9 | 10 | /** 11 | * Container component demonstrating attribute value stringification. 12 | * 13 | * @param {Record} props - The component props to be stringified. 14 | * @returns {JSX.Element} The rendered pre element with stringified props. 15 | * @public 16 | */ 17 | export const Container: React.FC = withSlots( 18 | 'MyAsAttributeValueContainer', 19 | function Containers(props: Record) { 20 | const content = Object.keys(props) 21 | .map(function createContent(key) { 22 | return `prop "${key}" is formatted as "${stringify(props[key])}"`; 23 | }) 24 | .join('\n'); 25 | 26 | return
{content}
; 27 | } 28 | ); 29 | -------------------------------------------------------------------------------- /packages/svg-parser/examples/custom-props.tsx: -------------------------------------------------------------------------------- 1 | import { parser } from '@bento/svg-parser'; 2 | 3 | /** 4 | * Custom Props Transformation Example 5 | * 6 | * This example demonstrates how to transform SVG attributes using custom prop transformations. 7 | * It shows how to: 8 | * - Convert 'class' to 'className' 9 | * - Convert 'stroke-width' to 'strokeWidth' 10 | */ 11 | const svgWithCustomProps = ` 12 | 13 | 14 | 15 | `; 16 | 17 | export function CustomPropsExample() { 18 | const parsedSvg = parser(svgWithCustomProps, { 19 | props: { 20 | // Transform 'class' attribute to 'className' 21 | class: (node) => ['className', node.getAttribute('class')!], 22 | // Transform 'stroke-width' to 'strokeWidth' 23 | 'stroke-width': (node) => ['strokeWidth', node.getAttribute('stroke-width')!] 24 | } 25 | }); 26 | return parsedSvg; 27 | } 28 | -------------------------------------------------------------------------------- /packages/container/examples/empty.tsx: -------------------------------------------------------------------------------- 1 | import { Container, type ContainerProps } from '@bento/container'; 2 | /* v8 ignore next */ 3 | import React from 'react'; 4 | 5 | export function EmptyExample(args: ContainerProps) { 6 | return ( 7 | 8 | {/* Backdrop overlay - no children needed */} 9 | 18 | 19 | {/* Spacer element */} 20 | 21 | 22 | {/* Decorative divider */} 23 | 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /packages/create-external-store/examples/create-store.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React, { useEffect, useSyncExternalStore } from 'react'; 3 | import { createStore } from '@bento/create-external-store'; 4 | import { withSlots } from '@bento/slots'; 5 | 6 | interface Example { 7 | [key: string]: any; 8 | } 9 | 10 | const store = createStore({ initial: 'data' }); 11 | 12 | /** 13 | * CreateStore component demonstrating external store creation and usage. 14 | * 15 | * @param {Example} props - The component props. 16 | * @returns {JSX.Element} The rendered component with store data. 17 | * @public 18 | */ 19 | export const CreateStore: React.FC = withSlots('CreatedStore', function Stored(props) { 20 | const data = useSyncExternalStore(store.subscribe, store.getSnapshot); 21 | 22 | useEffect( 23 | function addProps() { 24 | store.set(props); 25 | }, 26 | [props] 27 | ); 28 | 29 | return
{JSON.stringify(data, null, 2)}
; 30 | }); 31 | -------------------------------------------------------------------------------- /packages/overlay/overlay.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { Overlay as OverlayComponent } from './src/index.tsx'; 3 | import { Basic as BasicExample } from './examples/basic.tsx'; 4 | import { Modal as ModalExample } from './examples/modal.tsx'; 5 | import { Drawer as DrawerExample } from './examples/drawer.tsx'; 6 | import { UncontrolledWithTrigger as UncontrolledExample } from './examples/uncontrolled.tsx'; 7 | import { Popover as PopoverExample } from './examples/popover.tsx'; 8 | 9 | export default getMeta({ 10 | title: 'components/Overlay' 11 | }); 12 | 13 | export const Props = getComponentDocs(OverlayComponent); 14 | 15 | export const Basic = getStory(BasicExample); 16 | 17 | export const Modal = getStory(ModalExample); 18 | 19 | export const Drawer = getStory(DrawerExample); 20 | 21 | export const Uncontrolled = getStory(UncontrolledExample); 22 | 23 | export const Popover = getStory(PopoverExample); 24 | -------------------------------------------------------------------------------- /.grit/no_anonymous_function_expressions.grit: -------------------------------------------------------------------------------- 1 | // Detect anonymous function expressions (function() {} and function(params) {}) 2 | // Uses 'as $funcSig' to capture function signature for better span highlighting 3 | or { 4 | // Pattern for anonymous function with no parameters 5 | `function() { $body }` as $funcSig where { 6 | register_diagnostic( 7 | span = $funcSig, 8 | message = "Anonymous function expressions should be assigned to a named variable or converted to named functions for better debugging", 9 | severity = "error" 10 | ) 11 | }, 12 | // Pattern for anonymous function with parameters 13 | `function($params) { $body }` as $funcSig where { 14 | register_diagnostic( 15 | span = $funcSig, 16 | message = "Anonymous function expressions should be assigned to a named variable or converted to named functions for better debugging", 17 | severity = "error" 18 | ) 19 | } 20 | } -------------------------------------------------------------------------------- /packages/environment/environment.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { Environment } from './src/index.tsx'; 3 | import { ComponentLevelExample } from './examples/component-level.tsx'; 4 | import { CustomButtonExample } from './examples/custom-button.tsx'; 5 | import { IframeRenderingExample } from './examples/iframe-rendering.tsx'; 6 | import { OverrideProps } from './examples/override-props.tsx'; 7 | import { Override } from './examples/override.tsx'; 8 | 9 | export default getMeta({ 10 | title: 'components/Environment' 11 | }); 12 | 13 | export const API = getComponentDocs(Environment); 14 | 15 | export const Demo = getStory(Override); 16 | 17 | export const OverridePropsDemo = getStory(OverrideProps); 18 | 19 | export const ComponentLevelOverride = getStory(ComponentLevelExample); 20 | 21 | export const IframeRendering = getStory(IframeRenderingExample); 22 | 23 | export const Experimentation = getStory(CustomButtonExample); 24 | -------------------------------------------------------------------------------- /packages/listbox/examples/sections.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React from 'react'; 3 | import { ListBox, ListBoxItem, ListBoxSection, Header } from '@bento/listbox'; 4 | import style from './listbox.module.css'; 5 | 6 | /** 7 | * Example component demonstrating ListBox with static sections. 8 | * 9 | * @param {any} args - The component props. 10 | * @returns {JSX.Element} The rendered ListBox with sectioned items. 11 | * @public 12 | */ 13 | export function SectionsExample(args: any) { 14 | return ( 15 | 16 | 17 |
Main Dishes
18 | Chicken Teriyaki 19 | Salmon Bento 20 |
21 | 22 |
Side Dishes
23 | Pickled Vegetables 24 | Edamame 25 |
26 |
27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /packages/forward/forward.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getStory } from '@bento/storybook-addon-helpers'; 2 | import { BasicExample } from './examples/basic.tsx'; 3 | import { AlreadyWrapped } from './examples/already-wrapped.tsx'; 4 | import { NoRef } from './examples/no-ref.tsx'; 5 | import { RestParams } from './examples/rest-params.tsx'; 6 | 7 | export default getMeta({ 8 | title: 'higher-order components/forward' 9 | }); 10 | 11 | export const Basic = getStory(BasicExample, { 12 | args: { 13 | children: 'Basic Example', 14 | className: 'example-class' 15 | } 16 | }); 17 | 18 | export const Wrapped = getStory(AlreadyWrapped, { 19 | args: { 20 | children: 'Already Wrapped Example' 21 | } 22 | }); 23 | 24 | export const NoRefExample = getStory(NoRef, { 25 | args: { 26 | children: 'No Ref Example' 27 | } 28 | }); 29 | 30 | export const RestParamsExample = getStory(RestParams, { 31 | args: { 32 | children: 'Rest Parameters Example', 33 | className: 'rest-example' 34 | } 35 | }); 36 | -------------------------------------------------------------------------------- /packages/dismiss/examples/custom-label.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React, { useState } from 'react'; 3 | import { Dismiss } from '@bento/dismiss'; 4 | import { Container } from '@bento/container'; 5 | import { Text } from '@bento/text'; 6 | 7 | export function CustomLabel() { 8 | const [isOpen, setIsOpen] = useState(false); 9 | 10 | return ( 11 | <> 12 | {!isOpen && ( 13 | setIsOpen(true)}> 14 | Open Dialog 15 | 16 | )} 17 | {isOpen && ( 18 | 19 | setIsOpen(false)} ariaLabel="Close dialog" /> 20 | Dialog with Custom Label 21 | This dialog uses a custom aria-label for the dismiss button. 22 | setIsOpen(false)} ariaLabel="Close dialog" /> 23 | 24 | )} 25 | 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /packages/use-data-attributes/test/examples.browser.test.tsx: -------------------------------------------------------------------------------- 1 | import { Container } from '../examples/container.tsx'; 2 | import { render } from 'vitest-browser-react'; 3 | import { describe, it } from 'vitest'; 4 | import assume from 'assume'; 5 | import React from 'react'; 6 | 7 | describe('@bento/use-data-attributes examples', function bento() { 8 | describe('Container', function container() { 9 | it('should render the Container component', function test() { 10 | const { container } = render( 11 | 12 | ); 13 | const result = container.innerHTML; 14 | 15 | assume(result).includes('data-example="1 2 foo-bar"'); 16 | assume(result).includes('data-focused="true"'); 17 | assume(result).includes('data-loading="true"'); 18 | assume(result).includes('data-transform="rotate(45deg)"'); 19 | assume(result).includes('data-override="style className slots"'); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/use-svg-sprite/svg-sprite.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getStory } from '@bento/storybook-addon-helpers'; 2 | import { BasicUsage } from './examples/basic'; 3 | import { MultipleIcons } from './examples/multiple'; 4 | 5 | export default getMeta({ 6 | title: 'hooks/use-svg-sprite' 7 | }); 8 | 9 | export const useSVGSpriteMeta = { 10 | tags: ['!dev', 'stable'], 11 | parameters: { 12 | controls: { 13 | expanded: true 14 | } 15 | }, 16 | argTypes: { 17 | name: { 18 | description: 'The name of the SVG that should be added to the SVG sprite sheet', 19 | type: { name: 'string', required: true }, 20 | control: 'text' 21 | }, 22 | Graphic: { 23 | description: 'The component that renders the SVG content for the sprite sheet', 24 | type: { name: 'ReactElement', required: true }, 25 | control: 'object' 26 | } 27 | } 28 | }; 29 | 30 | export const BasicUsageStory = getStory(BasicUsage); 31 | 32 | export const MultipleIconStory = getStory(MultipleIcons); 33 | -------------------------------------------------------------------------------- /packages/scroll-lock/examples/hook.tsx: -------------------------------------------------------------------------------- 1 | import { useScrollLock } from '@bento/scroll-lock'; 2 | import { Container } from '@bento/container'; 3 | import { Text } from '@bento/text'; 4 | /* v8 ignore next */ 5 | import React from 'react'; 6 | 7 | export function HookExample() { 8 | // Use the hook directly for more control 9 | useScrollLock({ isDisabled: false }); 10 | 11 | return ( 12 | 13 | Using useScrollLock Hook 14 | This component uses the useScrollLock hook directly. 15 | Background scrolling is prevented while this component is mounted. 16 | 17 | {/* Create enough content to require scrolling */} 18 | {Array.from({ length: 50 }, (_, i) => ( 19 | 20 | This is paragraph {i + 1}. The useScrollLock hook prevents scrolling of this content. 21 | 22 | ))} 23 | 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /packages/radio/radio.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { Radio, RadioGroup } from './src/index.tsx'; 3 | import { ControlledExample } from './examples/controlled.tsx'; 4 | import { UncontrolledExample } from './examples/uncontrolled.tsx'; 5 | import { SingleRadioExample } from './examples/single-radio.tsx'; 6 | import { ErrorHandlingExample, ErrorHandlingExampleWithState } from './examples/error-handling.tsx'; 7 | 8 | export default getMeta({ 9 | title: 'components/Radio' 10 | }); 11 | 12 | export const RadioGroupProps = getComponentDocs(RadioGroup); 13 | 14 | export const RadioProps = getComponentDocs(Radio); 15 | 16 | export const Controlled = getStory(ControlledExample); 17 | 18 | export const Uncontrolled = getStory(UncontrolledExample); 19 | 20 | export const SingleRadio = getStory(SingleRadioExample); 21 | 22 | export const ErrorHandling = getStory(ErrorHandlingExample); 23 | 24 | export const ErrorHandlingWithState = getStory(ErrorHandlingExampleWithState); 25 | -------------------------------------------------------------------------------- /packages/dismiss/examples/basic.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React, { useState } from 'react'; 3 | import { Dismiss } from '@bento/dismiss'; 4 | import { Container } from '@bento/container'; 5 | import { Text } from '@bento/text'; 6 | 7 | export function Basic() { 8 | const [isOpen, setIsOpen] = useState(false); 9 | 10 | return ( 11 | <> 12 | {!isOpen && ( 13 | setIsOpen(true)}> 14 | Open Dialog 15 | 16 | )} 17 | {isOpen && ( 18 | 19 | setIsOpen(false)} /> 20 | Dialog Title 21 | This is a dialog with dismiss controls at the start and end. 22 | setIsOpen(false)}> 23 | Close 24 | 25 | setIsOpen(false)} /> 26 | 27 | )} 28 | 29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /packages/scroll-lock/examples/basic.tsx: -------------------------------------------------------------------------------- 1 | import { ScrollLock } from '@bento/scroll-lock'; 2 | import { Container } from '@bento/container'; 3 | import { Text } from '@bento/text'; 4 | /* v8 ignore next */ 5 | import React from 'react'; 6 | 7 | export function BasicExample() { 8 | return ( 9 | <> 10 | {/* Scrollable page content */} 11 | 12 | Page with Scroll Lock 13 | Try to scroll the page - scrolling is prevented when ScrollLock is active. 14 | 15 | {/* Create enough content to require scrolling */} 16 | {Array.from({ length: 50 }, (_, i) => ( 17 | 18 | This is paragraph {i + 1}. The page has enough content to scroll, but the ScrollLock component prevents 19 | background scrolling. 20 | 21 | ))} 22 | 23 | 24 | {/* ScrollLock prevents scrolling of the above content */} 25 | 26 | 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /packages/portal/test/portal.node.test.tsx: -------------------------------------------------------------------------------- 1 | import { Portal } from '@bento/portal'; 2 | import { describe, it } from 'vitest'; 3 | import { renderToString } from 'react-dom/server'; 4 | import React from 'react'; 5 | import assume from 'assume'; 6 | 7 | describe('@bento/portal (node)', function bentoNode() { 8 | describe('Portal SSR', function portalSSRTests() { 9 | it('does not render on server when mounted is false', function doesNotRenderOnServer() { 10 | const html = renderToString( 11 | 12 |
Server content
13 |
14 | ); 15 | 16 | assume(html).equals(''); 17 | }); 18 | 19 | it('does not render on server when mounted is true (SSR safety)', function ssrSafety() { 20 | // Even if mounted=true, Portal should not render on server because document is undefined 21 | const html = renderToString( 22 | 23 |
Server content
24 |
25 | ); 26 | 27 | assume(html).equals(''); 28 | }); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /packages/field-error/README.mdx: -------------------------------------------------------------------------------- 1 | import { 2 | Meta, 3 | ArgTypes, 4 | Story, 5 | Controls, 6 | Source, 7 | } from '@storybook/addon-docs/blocks'; 8 | import * as Stories from './field-error.stories.tsx'; 9 | import DefaultExample from './examples/default.tsx?raw'; 10 | 11 | 12 | 13 | # FieldError 14 | 15 | The `@bento/field-error` package provides the `FieldError` component, which is used to display error messages in form primitives, such as `RadioGroup` or `CheckboxGroup`. It is meant to be used in conjunction with form controls such as the `RadioGroup` or `CheckboxGroup` primitives. 16 | 17 | ## Installation 18 | 19 | ```bash 20 | npm install --save @bento/field-error 21 | ``` 22 | 23 | ## Props 24 | 25 | The following properties are available to be used on the `FieldError` component: 26 | 27 | 28 | 29 | ## Examples 30 | 31 | ### Default 32 | 33 | A simple usage of the `FieldError` component. The error message is only displayed when `isInvalid` is `true`. 34 | 35 | 36 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/error/examples/throws.tsx: -------------------------------------------------------------------------------- 1 | import { BentoError, type BentoErrorArgs } from '@bento/error'; 2 | /* v8 ignore next */ 3 | import React, { useCallback, type JSX } from 'react'; 4 | 5 | /** 6 | * Throws component renders a button that logs a BentoError to the console when clicked. 7 | * 8 | * @param {Object} props - The properties passed to the component. 9 | * @returns {JSX.Element} A button element that triggers the createError function on click. 10 | * 11 | * @example 12 | * 13 | * 14 | * @component 15 | */ 16 | export function Throws(props: BentoErrorArgs): JSX.Element { 17 | // 18 | // We're using useCallback here to prevent the function from being recreated 19 | // on every render as it's passed as a prop to the button component. 20 | // 21 | const createError = useCallback( 22 | function createError() { 23 | console.error(new BentoError(props)); 24 | }, 25 | [props] 26 | ); 27 | 28 | return ( 29 | 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /packages/types/README.md: -------------------------------------------------------------------------------- 1 | # @bento/types 2 | 3 | A shared TypeScript types package for the Bento library. This package centralizes common type definitions to reduce duplication, improve consistency, and simplify type maintenance across the Bento library. 4 | 5 | ## Installation 6 | 7 | ```bash 8 | npm install @bento/types 9 | ``` 10 | 11 | ## Usage 12 | 13 | Import types directly from the package. Eg: 14 | 15 | ```tsx 16 | import type { UnknownObject } from '@bento/types'; 17 | 18 | interface Data { 19 | elements: UnknownObject 20 | } 21 | ``` 22 | 23 | ## Contributing 24 | 25 | When adding new types to the library, follow these guidelines: 26 | 27 | 1. Organize types into appropriate categories 28 | 2. Document types with JSDoc comments 29 | 3. Add tests for the types in the `test` directory 30 | 4. Ensure exported types have descriptive names 31 | 5. Export them from the main `src/index.ts` file 32 | 33 | ## Testing 34 | 35 | Tests are written using [`Vitest's type testing approach`](https://vitest.dev/guide/testing-types). To run the tests for the types, run the following command: 36 | 37 | ```bash 38 | npm test 39 | ``` -------------------------------------------------------------------------------- /packages/box/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/button/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/divider/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/error/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/forward/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/heading/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/icon/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/input/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/listbox/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/overlay/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/portal/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/radio/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/slots/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/text/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/types/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/checkbox/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/container/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/environment/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/error/test/examples.browser.test.tsx: -------------------------------------------------------------------------------- 1 | import { Throws } from '../examples/throws.tsx'; 2 | import { render } from 'vitest-browser-react'; 3 | import { describe, it } from 'vitest'; 4 | import assume from 'assume'; 5 | import React from 'react'; 6 | 7 | describe('@bento/error examples', function bento() { 8 | describe('throws', function example() { 9 | it('logs an error to the console when the button is clicked', async function test() { 10 | const screen = render(); 11 | const consoleError = console.error; 12 | let error: Error | undefined; 13 | 14 | console.error = function handleError(err) { 15 | error = err; 16 | }; 17 | 18 | assume(screen.container.innerHTML).includes('Log bento error in console'); 19 | await screen.getByRole('button', { name: 'error' }).click(); 20 | 21 | console.error = consoleError; 22 | assume(error).is.instanceOf(Error); 23 | assume(error!.message).includes('@bento/error(example)'); 24 | assume(error!.message).includes('value here'); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/field-error/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/focus-lock/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/illustration/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/input/test/input.browser.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Input } from '@bento/input'; 3 | import { render } from 'vitest-browser-react'; 4 | import { describe, it, expect } from 'vitest'; 5 | import assume from 'assume'; 6 | 7 | describe('@bento/input', function bento() { 8 | describe('Input', function input() { 9 | it('renders an input element', async function test() { 10 | const { container } = render(); 11 | const input = container.querySelector('input[name="test-input"]'); 12 | assume(input).to.exist(); 13 | expect(input?.getAttribute('placeholder')).toBe('Enter text here'); 14 | }); 15 | 16 | it('passes attributes to the DOM', async function test() { 17 | const { container } = render(); 18 | const input = container.querySelector('input[type="file"]'); 19 | assume(input).to.exist(); 20 | expect(input?.getAttribute('multiple')).toBe(''); 21 | expect(input?.getAttribute('accept')).toBe('image/*'); 22 | }); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/pressable/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/scroll-lock/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/svg-parser/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/use-props/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/dismiss/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | -------------------------------------------------------------------------------- /packages/internal-props/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/use-svg-sprite/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/visually-hidden/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/create-external-store/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/to-attribute-value/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/use-data-attributes/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/storybook-addon-helpers/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/listbox/examples/sections-dynamic.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React from 'react'; 3 | import { ListBox, ListBoxItem, ListBoxSection, Header, Collection } from '@bento/listbox'; 4 | import style from './listbox.module.css'; 5 | 6 | /** 7 | * Example component demonstrating ListBox with dynamic sections. 8 | * 9 | * @param {any} args - The component props including categories array. 10 | * @returns {JSX.Element} The rendered ListBox with dynamic sections. 11 | * @public 12 | */ 13 | export function SectionsDynamicExample({ categories, ...args }: any) { 14 | return ( 15 | 16 | {(category: any) => ( 17 | 18 |
{category.name}
19 | 20 | {(item: { id: string; name: string }) => ( 21 | 22 | {item.name} 23 | 24 | )} 25 | 26 |
27 | )} 28 |
29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[javascript]": { 3 | "editor.formatOnSave": true, 4 | "editor.defaultFormatter": "biomejs.biome", 5 | "editor.codeActionsOnSave": { 6 | "source.organizeImports.biome": "never" 7 | } 8 | }, 9 | "[javascriptreact]": { 10 | "editor.formatOnSave": true, 11 | "editor.defaultFormatter": "biomejs.biome", 12 | "editor.codeActionsOnSave": { 13 | "source.organizeImports.biome": "never" 14 | } 15 | }, 16 | "[typescript]": { 17 | "editor.formatOnSave": true, 18 | "editor.defaultFormatter": "biomejs.biome", 19 | "editor.codeActionsOnSave": { 20 | "source.organizeImports.biome": "never" 21 | } 22 | }, 23 | "[typescriptreact]": { 24 | "editor.formatOnSave": true, 25 | "editor.defaultFormatter": "biomejs.biome", 26 | "editor.codeActionsOnSave": { 27 | "source.organizeImports.biome": "never" 28 | } 29 | }, 30 | "[json]": { 31 | "editor.formatOnSave": true, 32 | "editor.defaultFormatter": "biomejs.biome" 33 | }, 34 | "editor.codeActionsOnSave": { 35 | "quickfix.biome": "explicit", 36 | "source.organizeImports": "never" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/storybook-addon-helpers/src/index.ts: -------------------------------------------------------------------------------- 1 | import { type StorybookConfig } from '@storybook/react-vite'; 2 | import { type Indexer } from 'storybook/internal/types'; 3 | import { generateCSFPlugin } from './plugin.ts'; 4 | import { storiesIndexer } from './stories-indexer.ts'; 5 | export * from './getters.ts'; 6 | 7 | const STORIES_FILE_REGEX = /\.stories\.tsx$/; 8 | 9 | /** 10 | * Adds the custom stories indexer to the existing indexers. 11 | */ 12 | export const experimental_indexers: StorybookConfig['experimental_indexers'] = async function experimentalIndexers( 13 | existingIndexers 14 | ) { 15 | const customIndexer: Indexer = { 16 | test: STORIES_FILE_REGEX, 17 | createIndex: storiesIndexer 18 | }; 19 | 20 | if (!existingIndexers) { 21 | return [customIndexer]; 22 | } 23 | 24 | return [customIndexer, ...existingIndexers]; 25 | }; 26 | 27 | /** 28 | * Adds the plugin to the Storybook config. 29 | */ 30 | export const viteFinal: StorybookConfig['viteFinal'] = async function viteFinal(config) { 31 | config.plugins = config.plugins || []; 32 | config.plugins.push(generateCSFPlugin(STORIES_FILE_REGEX)); 33 | return config; 34 | }; 35 | -------------------------------------------------------------------------------- /apps/docs/.storybook/addons/why-did-you-render/why.tsx: -------------------------------------------------------------------------------- 1 | import { Reason, type Event } from './reason.tsx'; 2 | import React, { useMemo, type JSX } from 'react'; 3 | import { ListWrapper } from './list.tsx'; 4 | 5 | /** 6 | * A component that renders a list of reasons based on the provided events. 7 | * 8 | * @param {Object} props - The component props. 9 | * @param {Event[]} props.events - An array of event objects to be rendered. 10 | * @returns {JSX.Element} A div containing the rendered Reason components. 11 | */ 12 | export function Why({ events }: { events: Event[] }): JSX.Element { 13 | /** 14 | * Renders a Reason component for a given event. 15 | * 16 | * @param {Event} event - The event object containing the details to be rendered. 17 | * @param {number} index - The index of the event in the list. 18 | * @returns {JSX.Element} A Reason component with the event details. 19 | */ 20 | function renderReason(event: Event, index: number): JSX.Element { 21 | return ; 22 | } 23 | 24 | const rows: JSX.Element[] = useMemo(() => events.map(renderReason), [events]); 25 | return {rows}; 26 | } 27 | -------------------------------------------------------------------------------- /packages/slots/examples/forward-ref.tsx: -------------------------------------------------------------------------------- 1 | import { useProps } from '@bento/use-props'; 2 | import { withSlots, type Slots } from '@bento/slots'; 3 | /* v8 ignore next */ 4 | import React from 'react'; 5 | 6 | export interface ForwardRefExampleProps extends Slots, Omit, 'children'> { 7 | children?: React.ReactNode; 8 | } 9 | 10 | /** 11 | * Minimal example that demonstrates how refs supplied directly and through slots 12 | * are merged automatically when using `withSlots`. 13 | * 14 | * Note: No need to wrap with React.forwardRef - withSlots handles it automatically! 15 | * 16 | * @example 17 | * ```tsx 18 | * const outerRef = useRef(null); 19 | * const slotRef = useRef(null); 20 | * 21 | * 22 | * Inner content 23 | * 24 | * ``` 25 | */ 26 | export const ForwardRefExample = withSlots('SlotsForwardRefExample', function ForwardRefExample(...rest: any[]) { 27 | const { apply } = useProps(rest); 28 | 29 | return
; 30 | }); 31 | -------------------------------------------------------------------------------- /packages/checkbox/checkbox.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { Checkbox, CheckboxGroup } from './src/index.tsx'; 3 | import { CheckboxExample } from './examples/checkbox.tsx'; 4 | import { CheckboxControlledExample } from './examples/checkbox-controlled.tsx'; 5 | import { CheckboxGroupControlledExample } from './examples/checkbox-group-controlled.tsx'; 6 | import { CheckboxGroupIndeterminateExample } from './examples/checkbox-group-indeterminate.tsx'; 7 | import { CheckboxGroupExample } from './examples/checkbox-group.tsx'; 8 | 9 | export default getMeta({ 10 | title: 'components/Checkbox' 11 | }); 12 | 13 | export const CheckboxGroupProps = getComponentDocs(CheckboxGroup); 14 | 15 | export const CheckboxProps = getComponentDocs(Checkbox); 16 | 17 | export const CheckboxStory = getStory(CheckboxExample); 18 | 19 | export const CheckboxGroupStory = getStory(CheckboxGroupExample); 20 | 21 | export const CheckboxControlledStory = getStory(CheckboxControlledExample); 22 | 23 | export const CheckboxGroupIndeterminateStory = getStory(CheckboxGroupIndeterminateExample); 24 | 25 | export const CheckboxGroupControlledStory = getStory(CheckboxGroupControlledExample); 26 | -------------------------------------------------------------------------------- /packages/environment/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/environment 2 | 3 | ## 0.1.4 4 | 5 | ### Patch Changes 6 | 7 |
8 | Updated dependencies 9 | 10 | - @bento/slots@0.3.0 11 |
12 | 13 | ## 0.1.3 14 | 15 | ### Patch Changes 16 | 17 |
18 | Updated dependencies 19 | 20 | - @bento/slots@0.2.0 21 | - @bento/box@0.2.0 22 |
23 | 24 | ## 0.1.2 25 | 26 | ### Patch Changes 27 | 28 | - Adds documentation to all packages; no API or functionality changes. ([#23](https://github.com/godaddy/bento/pull/23) by @kawikabader) 29 | 30 |
31 | Updated dependencies 32 | 33 | - @bento/slots@0.1.3 34 | - @bento/box@0.1.1 35 |
36 | 37 | ## 0.1.1 38 | 39 | ### Patch Changes 40 | 41 |
42 | Updated dependencies 43 | 44 | - @bento/slots@0.1.1 45 |
46 | 47 | ## 0.1.0 48 | 49 | ### Minor Changes 50 | 51 | - chore: configure automated release workflow with changesets and GitHub Actions ([#168](https://github.com/godaddy/bento/pull/168) by @kbader-godaddy) 52 | 53 | ### Patch Changes 54 | 55 |
56 | Updated dependencies 57 | 58 | - @bento/slots@0.1.0 59 | - @bento/box@0.1.0 60 |
61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # Dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | 8 | # Local env files 9 | .env 10 | .env.local 11 | .env.development.local 12 | .env.test.local 13 | .env.production.local 14 | 15 | # Testing 16 | coverage 17 | coverage-html 18 | 19 | # Turbo 20 | .turbo 21 | 22 | # Vercel 23 | .vercel 24 | 25 | # Build Outputs 26 | .next/ 27 | out/ 28 | build 29 | dist 30 | 31 | # Compiled README files 32 | README.md 33 | 34 | 35 | # Debug 36 | npm-debug.log* 37 | yarn-debug.log* 38 | yarn-error.log* 39 | 40 | # Misc 41 | .DS_Store 42 | *.pem 43 | 44 | !.vscode/* 45 | storybook-static 46 | debug-storybook.log 47 | 48 | # Playwright 49 | /test-results/ 50 | /playwright-report/ 51 | /blob-report/ 52 | /playwright/.cache/ 53 | 54 | # When you a test failure, vitest automatically generates a screenshot of the 55 | # failure. This is the folder where the screenshots are stored. 56 | packages/**/test/__screenshots__/ 57 | 58 | # When running testing with VITE_NODE_DEBUG_DUMP=true it generates a .vite-node 59 | # folder dump folder of all the compiled assets. 60 | .vite-node 61 | 62 | # Claude 63 | .claude 64 | 65 | # Nx 66 | .nx/cache 67 | .nx/workspace-data 68 | -------------------------------------------------------------------------------- /packages/storybook-addon-helpers/src/stories-indexer.ts: -------------------------------------------------------------------------------- 1 | import { type StoryIndexInput } from 'storybook/internal/types'; 2 | import { getExportedVariables } from './getters-parser.ts'; 3 | 4 | /** 5 | * Custom indexer for a given *.stories.tsx file. 6 | * It will generate all the story indexes for the stories file, including the examples. 7 | * 8 | * @param storiesFilePath - The path to the *.stories.tsx file. 9 | * @returns The StoryIndexInput[] for the stories file. 10 | */ 11 | export async function storiesIndexer(storiesFilePath: string): Promise { 12 | const stories: StoryIndexInput[] = []; 13 | 14 | const exportedVariables = getExportedVariables({ filePath: storiesFilePath }); 15 | const title = exportedVariables.get('default')?.title ?? ''; 16 | 17 | if (!title) { 18 | return stories; 19 | } 20 | 21 | // add stories found (exported variables) in the *.stories.tsx file 22 | for (const [exportName, { tags }] of exportedVariables) { 23 | if (exportName === 'default') { 24 | continue; 25 | } 26 | 27 | stories.push({ 28 | title, 29 | tags, 30 | exportName, 31 | importPath: storiesFilePath, 32 | type: 'story' 33 | }); 34 | } 35 | 36 | return stories; 37 | } 38 | -------------------------------------------------------------------------------- /packages/focus-lock/examples/basic.tsx: -------------------------------------------------------------------------------- 1 | import { FocusLock } from '@bento/focus-lock'; 2 | import { Button } from '@bento/button'; 3 | import { Heading } from '@bento/heading'; 4 | import { Text } from '@bento/text'; 5 | import { Container } from '@bento/container'; 6 | /* v8 ignore next */ 7 | import React, { useState } from 'react'; 8 | 9 | export function BasicExample() { 10 | const [isOpen, setIsOpen] = useState(false); 11 | 12 | return ( 13 | <> 14 | 17 | 18 | {isOpen && ( 19 | 20 | 21 | {/* Single child receives data-focus-contained attribute */} 22 | 23 | Modal Title 24 | Modal content with contained focus. 25 | 28 | 29 | 30 | 31 | )} 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /packages/icon/icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { getMeta, getComponentDocs, getStory } from '@bento/storybook-addon-helpers'; 2 | import { Icon } from './src/index.tsx'; 3 | import { Awesome } from './examples/ondemand.tsx'; 4 | import { Loader } from './examples/loading.tsx'; 5 | import { Example } from './examples/icon.tsx'; 6 | 7 | export default getMeta({ 8 | title: 'components/Icon', 9 | component: Icon, 10 | argTypes: { 11 | flip: { 12 | options: ['none', 'horizontal', 'vertical'], 13 | control: { type: 'radio' } 14 | }, 15 | rotate: { 16 | options: [0, 90, 180, 270], 17 | control: { type: 'radio' } 18 | }, 19 | mode: { 20 | options: ['sprite', 'svg'], 21 | control: { type: 'radio' } 22 | } 23 | } 24 | }); 25 | 26 | export const Props = getComponentDocs(Icon); 27 | 28 | export const Demo = getStory(Example, { 29 | args: { 30 | width: 48, 31 | height: 48 32 | } 33 | }); 34 | 35 | export const Ondemand = getStory(Awesome, { 36 | args: { 37 | icon: 'boxes-stacked', 38 | width: 24, 39 | height: 24 40 | } 41 | }); 42 | 43 | export const Loading = getStory(Loader, { 44 | args: { 45 | fill: 'crimson', 46 | icon: 'dragon', 47 | width: 24, 48 | height: 24 49 | } 50 | }); 51 | -------------------------------------------------------------------------------- /packages/container/examples/building-block.tsx: -------------------------------------------------------------------------------- 1 | import { Container, type ContainerProps } from '@bento/container'; 2 | /* v8 ignore next */ 3 | import React, { type CSSProperties } from 'react'; 4 | 5 | // Example of building a custom Box component on top of Container 6 | export interface BoxProps extends ContainerProps { 7 | padding?: string | number; 8 | elevation?: 'low' | 'medium' | 'high'; 9 | } 10 | 11 | function Box({ padding = '16px', elevation = 'low', children, style, className = '', ...props }: BoxProps) { 12 | const boxStyle: CSSProperties = { 13 | padding, 14 | boxShadow: 15 | elevation === 'low' 16 | ? '0 1px 3px rgba(0,0,0,0.12)' 17 | : elevation === 'medium' 18 | ? '0 4px 6px rgba(0,0,0,0.16)' 19 | : '0 10px 20px rgba(0,0,0,0.19)', 20 | ...style 21 | }; 22 | 23 | return ( 24 | 25 | {children} 26 | 27 | ); 28 | } 29 | 30 | export function BuildingBlockExample(args: BoxProps) { 31 | const elevation = args.elevation || 'medium'; 32 | 33 | return ( 34 | 35 | This is a custom Box component built on Container 36 | 37 | ); 38 | } 39 | -------------------------------------------------------------------------------- /packages/field-error/test/field-error.node.test.tsx: -------------------------------------------------------------------------------- 1 | import { renderToString } from 'react-dom/server'; 2 | import { describe, it } from 'vitest'; 3 | import React from 'react'; 4 | import assume from 'assume'; 5 | import { FieldError } from '../src'; 6 | 7 | describe('@bento/field-error', function bento() { 8 | describe('FieldError', function fieldErrorTests() { 9 | it('renders error message when isInvalid is true', function rendersWhenInvalid() { 10 | const result = renderToString(Error message); 11 | 12 | assume(result).includes('Error message'); 13 | }); 14 | 15 | it('does not render when isInvalid is undefined', function doesNotRenderWhenUndefined() { 16 | const result = renderToString(Error message); 17 | 18 | assume(result).equals(''); 19 | }); 20 | 21 | it('passes through other props', function passesOtherProps() { 22 | const result = renderToString( 23 | 24 | Error message 25 | 26 | ); 27 | 28 | assume(result).includes('data-testid="error-id"'); 29 | assume(result).includes('class="custom-error"'); 30 | }); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /packages/divider/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @bento/divider 2 | 3 | ## 0.1.4 4 | 5 | ### Patch Changes 6 | 7 |
8 | Updated dependencies 9 | 10 | - @bento/slots@0.3.0 11 | - @bento/use-props@0.2.1 12 |
13 | 14 | ## 0.1.3 15 | 16 | ### Patch Changes 17 | 18 |
19 | Updated dependencies 20 | 21 | - @bento/use-props@0.2.0 22 | - @bento/slots@0.2.0 23 |
24 | 25 | ## 0.1.2 26 | 27 | ### Patch Changes 28 | 29 | - Adds documentation to all packages; no API or functionality changes. ([#23](https://github.com/godaddy/bento/pull/23) by @kawikabader) 30 | 31 |
32 | Updated dependencies 33 | 34 | - @bento/use-props@0.1.1 35 | - @bento/slots@0.1.3 36 |
37 | 38 | ## 0.1.1 39 | 40 | ### Patch Changes 41 | 42 |
43 | Updated dependencies 44 | 45 | - @bento/slots@0.1.1 46 |
47 | 48 | ## 0.1.0 49 | 50 | ### Minor Changes 51 | 52 | - chore: configure automated release workflow with changesets and GitHub Actions ([#168](https://github.com/godaddy/bento/pull/168) by @kbader-godaddy) 53 | 54 | ### Patch Changes 55 | 56 |
57 | Updated dependencies 58 | 59 | - @bento/use-props@0.1.0 60 | - @bento/slots@0.1.0 61 |
62 | -------------------------------------------------------------------------------- /packages/create-external-store/test/examples.browser.test.tsx: -------------------------------------------------------------------------------- 1 | import { CreateStore } from '../examples/create-store.tsx'; 2 | import { render } from 'vitest-browser-react'; 3 | import { Icon } from '../examples/icon.tsx'; 4 | import { describe, it } from 'vitest'; 5 | import assume from 'assume'; 6 | import React from 'react'; 7 | 8 | describe('@bento/create-external-store examples', function bento() { 9 | describe('icon', function iconExample() { 10 | it('renders the icon with the correct icon name', function name() { 11 | const { container } = render(); 12 | 13 | assume(container.innerHTML).includes('octopus-sausages'); 14 | }); 15 | 16 | it('renders nothing when the icon is not found', function notFound() { 17 | const { container } = render(); 18 | 19 | assume(container.innerHTML).equals(''); 20 | }); 21 | }); 22 | 23 | describe('CreateStore', function createStoreExample() { 24 | it('renders the initial data', function initialData() { 25 | const { container } = render(); 26 | 27 | assume(container.innerHTML).includes(JSON.stringify({ initial: 'data', hello: 'world', foo: ['bar'] }, null, 2)); 28 | }); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /packages/storybook-addon-helpers/test/fixtures/components/imported-components.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { type ExternalProps, type NestedExternalProps } from './external-props'; 3 | 4 | /** 5 | * Component that uses imported props 6 | */ 7 | export function ImportedPropsComponent(props: ExternalProps) { 8 | return ( 9 |
10 |

{props.externalProp}

11 | {props.optionalProp && {props.optionalProp}} 12 |
13 | ); 14 | } 15 | 16 | /** 17 | * Component with nested external props 18 | */ 19 | export function NestedImportComponent(props: NestedExternalProps) { 20 | return ( 21 |
22 |

Enabled: {props.config.enabled.toString()}

23 |

Timeout: {props.config.settings.timeout}

24 |
25 | ); 26 | } 27 | 28 | // Local interface extending external 29 | export interface LocalExtendedProps extends ExternalProps { 30 | /** Local additional property */ 31 | localProp: boolean; 32 | } 33 | 34 | /** 35 | * Component extending external props with local props 36 | */ 37 | export function ExtendedPropsComponent(props: LocalExtendedProps) { 38 | return ( 39 |
40 |

{props.externalProp}

41 |

Local: {props.localProp.toString()}

42 |
43 | ); 44 | } 45 | -------------------------------------------------------------------------------- /packages/overlay/examples/basic.tsx: -------------------------------------------------------------------------------- 1 | /* v8 ignore next */ 2 | import React, { useState } from 'react'; 3 | import { Overlay } from '@bento/overlay'; 4 | import { Container } from '@bento/container'; 5 | import { Button } from '@bento/button'; 6 | import { Text } from '@bento/text'; 7 | 8 | export function Basic() { 9 | const [open, setOpen] = useState(false); 10 | 11 | return ( 12 | <> 13 | 14 | 15 | {open && ( 16 | 30 | Basic Overlay 31 | This is a simple overlay example using only the content slot. 32 | 33 | 34 | )} 35 | 36 | 37 | ); 38 | } 39 | -------------------------------------------------------------------------------- /packages/internal-props/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { shared } from '../../configs/tsup.config.mjs'; 2 | import { version } from './package.json'; 3 | import { defineConfig } from 'tsup'; 4 | 5 | export default defineConfig({ 6 | ...shared, 7 | entry: ['src/index.ts'], 8 | 9 | /** 10 | * Introduces the version of the package as a define variable in the build, 11 | * allowing the code to reference major, minor, and patch versions numbers. 12 | * 13 | * @param {import('esbuild').BuildOptions} options - The options object passed to esbuild. 14 | * @returns {void} 15 | * @private 16 | */ 17 | esbuildOptions(options) { 18 | // 19 | // Package versions can include prerelease tags (e.g. 1.2.3-alpha) or build metadata 20 | // (e.g. 1.2.3+20230315). We only want the core version numbers for build-time 21 | // constants, so we use regex to extract just the major.minor.patch parts. 22 | // 23 | // @see https://semver.org/ 24 | // 25 | const versionMatch = version.match(/^(\d+)\.(\d+)\.(\d+)/); 26 | const semver = versionMatch ? versionMatch.slice(1) : ['0', '0', '0']; 27 | 28 | options.define ??= {}; 29 | ['major', 'minor', 'patch'].forEach(function defineVersion(key, index) { 30 | options.define[key] = JSON.stringify(semver[index]); 31 | }); 32 | } 33 | }); 34 | --------------------------------------------------------------------------------