diff --git a/semcore/pills/package.json b/semcore/pills/package.json index 661420565e..704f606a14 100644 --- a/semcore/pills/package.json +++ b/semcore/pills/package.json @@ -9,7 +9,7 @@ "author": "UI-kit team ", "license": "MIT", "scripts": { - "build": "pnpm semcore-builder --source=js && pnpm vite build" + "build": "pnpm semcore-builder && pnpm vite build" }, "exports": { "require": "./lib/cjs/index.js", diff --git a/semcore/pills/src/Pills.jsx b/semcore/pills/src/Pills.tsx similarity index 56% rename from semcore/pills/src/Pills.jsx rename to semcore/pills/src/Pills.tsx index cd526405b5..935caf3e8f 100644 --- a/semcore/pills/src/Pills.jsx +++ b/semcore/pills/src/Pills.tsx @@ -1,35 +1,39 @@ import { NeighborLocation, Box, useNeighborLocationDetect } from '@semcore/base-components'; +import type { Intergalactic, IRootComponentProps } from '@semcore/core'; import { createComponent, Component, sstyled, Root } from '@semcore/core'; import addonTextChildren from '@semcore/core/lib/utils/addonTextChildren'; import a11yEnhance from '@semcore/core/lib/utils/enhances/a11yEnhance'; import React from 'react'; +import type { IntergalacticPillsComponent, PillProps, PillsComponent, PillsHandlers, PillsProps } from './Pills.type'; import style from './style/pills.shadow.css'; -const optionsA11yEnhance = { - onNeighborChange: (neighborElement, props) => { - if (neighborElement) { - neighborElement.focus(); - if (props.behavior === 'auto') { - neighborElement.click(); - } - } - }, - childSelector: (props) => - props.behavior === 'auto' ? ['role', 'radio'] : ['role', 'tab'], -}; - -class RootPills extends Component { +class RootPills extends Component { static displayName = 'Pills'; static style = style; - static defaultProps = ({ behavior }) => ({ + static defaultProps = ({ behavior }: PillsProps) => ({ size: 'm', defaultValue: null, behavior: behavior ?? 'auto', }); - itemValues = []; - static enhance = [a11yEnhance(optionsA11yEnhance)]; + itemValues: Array = []; + + static enhance = [a11yEnhance({ + onNeighborChange: (neighborElement, props) => { + if (neighborElement) { + neighborElement.focus(); + if (props.behavior === 'auto') { + neighborElement.click(); + } + } + }, + childSelector: (props) => { + const selector = props.behavior === 'auto' ? ['role', 'radio'] : ['role', 'tab']; + + return selector as [string, string]; + }, + })] as const; uncontrolledProps() { return { @@ -37,22 +41,23 @@ class RootPills extends Component { }; } - bindHandlerClick = (value) => (e) => { + bindHandlerClick = (value: PillProps['value']) => (e: React.MouseEvent) => { this.handlers.value(value, e); }; - bindHandleKeyDown = (value) => (event) => { - if (event.key === 'Enter' || event.key === ' ') { - event.preventDefault(); - this.handlers.value(value, event); + bindHandleKeyDown = (value: PillProps['value']) => (e: React.KeyboardEvent) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + this.handlers.value(value, e); } }; - getItemProps(props, index) { + getItemProps(props: PillProps, index: number) { const { value, size, disabled, behavior } = this.asProps; const isSelected = value === props.value; this.itemValues[index] = props.value; + return { index: index, size, @@ -65,23 +70,6 @@ class RootPills extends Component { }; } - changeIndex = (startIndex, type) => { - let selectable = false; - - while (!selectable && startIndex >= 0 && startIndex < this.itemValues.length) { - if (type === 'increment') startIndex++; - if (type === 'decrement') startIndex--; - - const element = this.itemRefs[startIndex]; - - if (element?.disabled === false) { - selectable = true; - } - } - - return startIndex >= 0 && startIndex < this.itemValues.length ? startIndex : undefined; - }; - render() { const SPills = Root; const { Children, styles, controlsLength, disabled, behavior, value } = this.asProps; @@ -101,18 +89,19 @@ class RootPills extends Component { } } -function Pill(props) { +type PillPropsFromRoot = ReturnType['getItemProps']>; + +function Pill(props: PillPropsFromRoot & PillProps & IRootComponentProps) { const SPill = Root; const { Children, styles, addonLeft, addonRight, selected, disabled, index, behavior } = props; const neighborLocation = useNeighborLocationDetect(index); - const roleAreaProps = {}; - if (behavior === 'auto') { - roleAreaProps.role = 'radio'; - roleAreaProps['aria-checked'] = selected; - } else { - roleAreaProps.role = 'tab'; - roleAreaProps['aria-selected'] = selected; - } + + const roleAreaProps = { + 'role': behavior === 'auto' ? 'radio' : 'tab', + 'aria-checked': behavior === 'auto' ? selected : undefined, + 'aria-selected': behavior !== 'auto' ? selected : undefined, + }; + return sstyled(styles)( ); } -function Addon(props) { +function Addon(props: IRootComponentProps) { const SAddon = Root; return sstyled(props.styles)(); } +export const wrapPills = (wrapper: ( + props: Intergalactic.InternalTypings.UntypeRefAndTag< + Intergalactic.InternalTypings.ComponentPropsNesting + > & + PropsExtending, +) => React.ReactNode) => wrapper as IntergalacticPillsComponent; + const Pills = createComponent(RootPills, { Item: [Pill, { Text, Addon }], -}); - -export const wrapPills = (wrapper) => wrapper; +}) as unknown as PillsComponent; export default Pills; diff --git a/semcore/pills/src/index.d.ts b/semcore/pills/src/Pills.type.ts similarity index 80% rename from semcore/pills/src/index.d.ts rename to semcore/pills/src/Pills.type.ts index dbd01d15e4..a30a342e07 100644 --- a/semcore/pills/src/index.d.ts +++ b/semcore/pills/src/Pills.type.ts @@ -50,10 +50,10 @@ export type PillsContext = { }; export type PillsHandlers = { - value: (value: PillsValue) => void; + value: PillsValue; }; -type IntergalacticPillsComponent = (< +export type IntergalacticPillsComponent = (< Value extends PillsValue, Tag extends Intergalactic.Tag = 'div', >( @@ -68,21 +68,9 @@ type IntergalacticPillsComponent = (< ) => Intergalactic.InternalTypings.ComponentRenderingResults) & Intergalactic.InternalTypings.ComponentAdditive<'div', 'div', PillsProps>; -declare const Pills: IntergalacticPillsComponent & { +export type PillsComponent = IntergalacticPillsComponent & { Item: Intergalactic.Component<'button', PillProps, [handlers: PillsHandlers]> & { Text: typeof Box; Addon: typeof Box; }; }; - -declare const wrapPills: ( - wrapper: ( - props: Intergalactic.InternalTypings.UntypeRefAndTag< - Intergalactic.InternalTypings.ComponentPropsNesting - > & - PropsExtending, - ) => React.ReactNode, -) => IntergalacticPillsComponent; -export { wrapPills }; - -export default Pills; diff --git a/semcore/pills/src/index.js b/semcore/pills/src/index.js deleted file mode 100644 index ef9136cb01..0000000000 --- a/semcore/pills/src/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from './Pills'; -export * from './Pills'; diff --git a/semcore/pills/src/index.ts b/semcore/pills/src/index.ts new file mode 100644 index 0000000000..dfe627ea67 --- /dev/null +++ b/semcore/pills/src/index.ts @@ -0,0 +1,2 @@ +export { default, wrapPills } from './Pills'; +export * from './Pills.type'; diff --git a/semcore/pills/vite.config.ts b/semcore/pills/vite.config.ts index 0991a16528..90f46b4cb2 100644 --- a/semcore/pills/vite.config.ts +++ b/semcore/pills/vite.config.ts @@ -7,7 +7,7 @@ export default mergeConfig( defineConfig({ build: { lib: { - entry: './src/index.js', + entry: './src/index.ts', }, rollupOptions: { external: ['react', 'react-dom', 'react/jsx-runtime', /@babel\/runtime\/*/, /@semcore\/*/],