@bitrise/bitkit-v2 0.3.481-beta.3087 → 0.3.481-beta.3091

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,7 +18,7 @@ export interface BitkitFilterProps extends Omit<BoxProps, 'children'> {
18
18
  * cap the bar's content with it (padded 32 on both sides), or `'full'` for a full-width column
19
19
  * (24 at the start, like the default `BitkitPageHeader`, and 32 at the end).
20
20
  *
21
- * Without it the bar has the tighter inset of a filter above a table. Desktop only.
21
+ * Without it the bar has no padding of its own: place it with style props, like any block. Desktop only.
22
22
  */
23
23
  contentWidth?: `${number}rem` | 'full';
24
24
  /**
@@ -207,24 +207,20 @@ var BitkitFilter = forwardRef((props, ref) => {
207
207
  ref: focusTarget,
208
208
  children: [/* @__PURE__ */ jsxs(Box, {
209
209
  css: styles.filters,
210
- children: [
211
- showIcon && /* @__PURE__ */ jsx(Box, {
210
+ children: [/* @__PURE__ */ jsxs(Box, {
211
+ css: styles.items,
212
+ children: [showIcon && /* @__PURE__ */ jsx(Box, {
212
213
  css: styles.icon,
213
214
  children: /* @__PURE__ */ jsx(IconFilter, {})
214
- }),
215
- /* @__PURE__ */ jsx(Box, {
216
- css: styles.items,
217
- children: filters
218
- }),
219
- showClear && isDirty && /* @__PURE__ */ jsx(BitkitButton, {
220
- ...clearProps,
221
- flexShrink: "0",
222
- icon: IconCross,
223
- size: "sm",
224
- variant: "tertiary",
225
- children: "Clear filters"
226
- })
227
- ]
215
+ }), filters]
216
+ }), showClear && isDirty && /* @__PURE__ */ jsx(BitkitButton, {
217
+ ...clearProps,
218
+ flexShrink: "0",
219
+ icon: IconCross,
220
+ size: "sm",
221
+ variant: "tertiary",
222
+ children: "Clear filters"
223
+ })]
228
224
  }), searches.length > 0 && /* @__PURE__ */ jsx(Box, {
229
225
  css: styles.searchBlock,
230
226
  children: searches
@@ -1 +1 @@
1
- {"version":3,"file":"BitkitFilter.js","names":[],"sources":["../../../lib/components/BitkitFilter/BitkitFilter.tsx"],"sourcesContent":["import { Box, type BoxProps } from '@chakra-ui/react/box';\nimport { Drawer } from '@chakra-ui/react/drawer';\nimport { Portal } from '@chakra-ui/react/portal';\n// `chakra.button`: the mobile \"Filters\" button carries a count badge, which BitkitButton's string-only label can't.\nimport { chakra, useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { forwardRef, type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport useResponsive from '../../hooks/useResponsive';\nimport { IconCross, IconFilter } from '../../icons';\nimport { usePortalContext } from '../../utilities/BitkitPortalContext';\nimport { flattenChildren } from '../../utilities/flattenChildren';\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport BitkitBadge from '../BitkitBadge/BitkitBadge';\nimport BitkitButton from '../BitkitButton/BitkitButton';\nimport BitkitCloseButton from '../BitkitCloseButton/BitkitCloseButton';\nimport { FilterContextProvider, type FilterStatus } from './BitkitFilter.context';\nimport BitkitFilterAdd from './BitkitFilterAdd';\nimport BitkitFilterDateRange from './BitkitFilterDateRange';\nimport BitkitFilterSearch from './BitkitFilterSearch';\nimport BitkitFilterSelect from './BitkitFilterSelect';\nimport BitkitFilterSwitch from './BitkitFilterSwitch';\n\nexport interface BitkitFilterProps extends Omit<BoxProps, 'children'> {\n /**\n * The filters: `BitkitFilter.Switch`, `.Select`, `.DateRange`, `.Add` and `.Search`, in the\n * order they appear. `.Search` always sits at the end of the bar.\n */\n children: ReactNode;\n /**\n * Where a capped content block sits: `center` over a centred page column, `start` over one that\n * starts against a sidebar. Pass the same alignment as the page header and content below it.\n * Only applies with a `contentWidth` in rems. Desktop only.\n */\n contentAlign?: 'center' | 'start';\n /**\n * Lines the bar up with the page content below it, for a bar under a page header: it gains a\n * bottom border and the page's inline padding. Pass the content column's `max-width` in rems to\n * cap the bar's content with it (padded 32 on both sides), or `'full'` for a full-width column\n * (24 at the start, like the default `BitkitPageHeader`, and 32 at the end).\n *\n * Without it the bar has the tighter inset of a filter above a table. Desktop only.\n */\n contentWidth?: `${number}rem` | 'full';\n /**\n * Forces the desktop bar or the mobile \"Filters\" dialog. Defaults to the viewport: mobile below the\n * tablet breakpoint. The mobile dialog is made for narrow screens; from tablet up it is a 320px drawer.\n */\n device?: 'desktop' | 'mobile';\n /**\n * Called once on \"Clear filters\" in place of handing each changed filter its `resetValue` — for a\n * page that resets them all in one write, e.g. one URL update. The `resetValue`s still decide when\n * the button shows.\n */\n onClear?: () => void;\n /**\n * Shows \"Clear filters\" while any filter differs from its `resetValue`. It hands each of those\n * filters its `resetValue` back through its own `onValueChange`, or calls `onClear`.\n */\n showClear?: boolean;\n /** Shows the filter icon at the start of the bar. Desktop only. */\n showIcon?: boolean;\n /** `loading`: while the page's data loads, the filters can't be opened, removed or cleared. The search stays usable. */\n state?: 'loading';\n}\n\nconst toggle = (set: ReadonlySet<string>, id: string, isIn: boolean) => {\n if (set.has(id) === isIn) return set;\n const next = new Set(set);\n if (isIn) next.add(id);\n else next.delete(id);\n return next;\n};\n\n/**\n * A bar of filters above a list. Each filter is a controlled sub-component with its own `value` and\n * `onValueChange`; the bar lays them out and offers \"Clear filters\" across all of them.\n *\n * Below the tablet breakpoint the bar collapses into a \"Filters\" button opening a full-screen dialog,\n * where every filter is a field opening its own view. A filter still applies on its view's \"Apply\".\n */\nconst BitkitFilter = forwardRef<HTMLDivElement, BitkitFilterProps>((props, ref) => {\n const {\n children,\n contentAlign,\n contentWidth,\n css,\n device,\n onClear,\n showClear = true,\n showIcon = true,\n state,\n ...rest\n } = props;\n const { isMobile: isMobileViewport } = useResponsive();\n const isMobile = device ? device === 'mobile' : isMobileViewport;\n const isDisabled = state === 'loading';\n const { disablePortal } = usePortalContext();\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n const recipe = useSlotRecipe({ key: 'filter' });\n let pageLayout: 'capped' | 'full' | undefined;\n if (contentWidth) pageLayout = contentWidth === 'full' ? 'full' : 'capped';\n const styles = recipe({ contentAlign: pageLayout === 'capped' ? contentAlign : undefined, pageLayout });\n\n const resets = useRef(new Map<string, () => void>());\n const [dirtyIds, setDirtyIds] = useState<ReadonlySet<string>>(new Set());\n const [activeIds, setActiveIds] = useState<ReadonlySet<string>>(new Set());\n\n const register = useCallback((id: string, reset: () => void) => {\n resets.current.set(id, reset);\n }, []);\n\n const setStatus = useCallback((id: string, { isActive, isDirty }: FilterStatus) => {\n setDirtyIds((prev) => toggle(prev, id, isDirty));\n setActiveIds((prev) => toggle(prev, id, isActive));\n }, []);\n\n const unregister = useCallback(\n (id: string) => {\n resets.current.delete(id);\n setStatus(id, { isActive: false, isDirty: false });\n },\n [setStatus],\n );\n\n const context = useMemo(\n () => ({ isDisabled, isMobile, register, setStatus, styles, unregister }),\n [isDisabled, isMobile, register, setStatus, styles, unregister],\n );\n\n const filters: ReactNode[] = [];\n const searches: ReactNode[] = [];\n // Flattened, so a filter grouped in a fragment is still sorted to the right place.\n flattenChildren(children).forEach((child) => {\n if (child.type === BitkitFilterSearch) searches.push(child);\n else filters.push(child);\n });\n\n const isDirty = dirtyIds.size > 0;\n const activeCount = activeIds.size;\n // The \"Clear filters\" button goes away (or is disabled) once nothing differs, so focus then moves\n // to the first control of the cleared filters rather than dropping to the page. Only if it hasn't\n // gone anywhere else meanwhile, e.g. while a slow reset was under way.\n const focusTarget = useRef<HTMLDivElement>(null);\n const isFocusPending = useRef(false);\n const clearAll = () => {\n if (isDisabled) return;\n isFocusPending.current = true;\n // Called off once focus lands anywhere, so a clear that never fully lands can't pull it in later.\n document.addEventListener(\n 'focusin',\n () => {\n isFocusPending.current = false;\n },\n { once: true },\n );\n if (onClear) onClear();\n else dirtyIds.forEach((id) => resets.current.get(id)?.());\n };\n useEffect(() => {\n if (!isFocusPending.current || isDirty) return;\n isFocusPending.current = false;\n const active = document.activeElement;\n if (active && active !== document.body && !active.matches('[data-filter-clear]')) return;\n focusTarget.current?.querySelector<HTMLElement>('button:not(:disabled), input:not(:disabled)')?.focus();\n }, [isDirty]);\n\n // While the page loads, the controls are only `aria-disabled`, so they keep a focus handed to them.\n // `data-disabled` takes them out of the hover and active styles too.\n const disabledProps = { 'aria-disabled': isDisabled || undefined, 'data-disabled': isDisabled ? '' : undefined };\n const clearProps = { ...disabledProps, 'data-filter-clear': '', onClick: clearAll };\n\n if (isMobile) {\n return (\n <FilterContextProvider value={context}>\n <Box css={css} ref={ref} {...rest}>\n <Box css={styles.mobileBar} ref={isDialogOpen ? undefined : focusTarget}>\n <chakra.button\n aria-expanded={isDialogOpen}\n aria-haspopup=\"dialog\"\n aria-label={`Filters, ${activeCount} applied`}\n {...disabledProps}\n css={styles.mobileTrigger}\n onClick={() => !isDisabled && setIsDialogOpen(true)}\n type=\"button\"\n >\n <IconFilter size=\"16\" />\n Filters\n <BitkitBadge colorVariant={activeCount ? 'purple' : 'neutral'}>{activeCount}</BitkitBadge>\n </chakra.button>\n {showClear && isDirty && (\n <BitkitButton {...clearProps} icon={IconCross} size=\"sm\" variant=\"tertiary\">\n Clear filters\n </BitkitButton>\n )}\n </Box>\n {searches}\n {/* Kept mounted while closed: the filters inside register their values with the bar. */}\n <Drawer.Root\n lazyMount={false}\n onOpenChange={({ open }) => setIsDialogOpen(open)}\n open={isDialogOpen}\n unmountOnExit={false}\n >\n <Portal disabled={disablePortal}>\n <Drawer.Positioner>\n <Drawer.Content>\n <Box css={styles.mobileHeader}>\n <Drawer.Title css={styles.mobileTitle} unstyled>\n Filters\n </Drawer.Title>\n <Drawer.CloseTrigger asChild unstyled>\n <BitkitCloseButton size=\"sm\" />\n </Drawer.CloseTrigger>\n </Box>\n <Drawer.Body css={styles.mobileBody} ref={isDialogOpen ? focusTarget : undefined}>\n {filters}\n </Drawer.Body>\n <Drawer.Footer>\n <Box css={styles.mobileFooter}>\n {showClear && (\n <BitkitButton\n {...clearProps}\n size=\"md\"\n state={isDirty ? undefined : 'disabled'}\n variant=\"secondary\"\n >\n Clear filters\n </BitkitButton>\n )}\n <BitkitButton onClick={() => setIsDialogOpen(false)} size=\"md\">\n Show results\n </BitkitButton>\n </Box>\n </Drawer.Footer>\n </Drawer.Content>\n </Drawer.Positioner>\n </Portal>\n </Drawer.Root>\n </Box>\n </FilterContextProvider>\n );\n }\n\n return (\n <FilterContextProvider value={context}>\n <Box css={[styles.root, css]} ref={ref} {...rest}>\n <Box css={styles.content} maxWidth={contentWidth === 'full' ? undefined : contentWidth} ref={focusTarget}>\n <Box css={styles.filters}>\n {showIcon && (\n <Box css={styles.icon}>\n <IconFilter />\n </Box>\n )}\n <Box css={styles.items}>{filters}</Box>\n {showClear && isDirty && (\n <BitkitButton {...clearProps} flexShrink=\"0\" icon={IconCross} size=\"sm\" variant=\"tertiary\">\n Clear filters\n </BitkitButton>\n )}\n </Box>\n {searches.length > 0 && <Box css={styles.searchBlock}>{searches}</Box>}\n </Box>\n </Box>\n </FilterContextProvider>\n );\n});\n\nBitkitFilter.displayName = 'BitkitFilter';\n\nexport default withSubComponents(BitkitFilter, {\n Add: BitkitFilterAdd,\n DateRange: BitkitFilterDateRange,\n Search: BitkitFilterSearch,\n Select: BitkitFilterSelect,\n Switch: BitkitFilterSwitch,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"BitkitFilter.js","names":[],"sources":["../../../lib/components/BitkitFilter/BitkitFilter.tsx"],"sourcesContent":["import { Box, type BoxProps } from '@chakra-ui/react/box';\nimport { Drawer } from '@chakra-ui/react/drawer';\nimport { Portal } from '@chakra-ui/react/portal';\n// `chakra.button`: the mobile \"Filters\" button carries a count badge, which BitkitButton's string-only label can't.\nimport { chakra, useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { forwardRef, type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport useResponsive from '../../hooks/useResponsive';\nimport { IconCross, IconFilter } from '../../icons';\nimport { usePortalContext } from '../../utilities/BitkitPortalContext';\nimport { flattenChildren } from '../../utilities/flattenChildren';\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport BitkitBadge from '../BitkitBadge/BitkitBadge';\nimport BitkitButton from '../BitkitButton/BitkitButton';\nimport BitkitCloseButton from '../BitkitCloseButton/BitkitCloseButton';\nimport { FilterContextProvider, type FilterStatus } from './BitkitFilter.context';\nimport BitkitFilterAdd from './BitkitFilterAdd';\nimport BitkitFilterDateRange from './BitkitFilterDateRange';\nimport BitkitFilterSearch from './BitkitFilterSearch';\nimport BitkitFilterSelect from './BitkitFilterSelect';\nimport BitkitFilterSwitch from './BitkitFilterSwitch';\n\nexport interface BitkitFilterProps extends Omit<BoxProps, 'children'> {\n /**\n * The filters: `BitkitFilter.Switch`, `.Select`, `.DateRange`, `.Add` and `.Search`, in the\n * order they appear. `.Search` always sits at the end of the bar.\n */\n children: ReactNode;\n /**\n * Where a capped content block sits: `center` over a centred page column, `start` over one that\n * starts against a sidebar. Pass the same alignment as the page header and content below it.\n * Only applies with a `contentWidth` in rems. Desktop only.\n */\n contentAlign?: 'center' | 'start';\n /**\n * Lines the bar up with the page content below it, for a bar under a page header: it gains a\n * bottom border and the page's inline padding. Pass the content column's `max-width` in rems to\n * cap the bar's content with it (padded 32 on both sides), or `'full'` for a full-width column\n * (24 at the start, like the default `BitkitPageHeader`, and 32 at the end).\n *\n * Without it the bar has no padding of its own: place it with style props, like any block. Desktop only.\n */\n contentWidth?: `${number}rem` | 'full';\n /**\n * Forces the desktop bar or the mobile \"Filters\" dialog. Defaults to the viewport: mobile below the\n * tablet breakpoint. The mobile dialog is made for narrow screens; from tablet up it is a 320px drawer.\n */\n device?: 'desktop' | 'mobile';\n /**\n * Called once on \"Clear filters\" in place of handing each changed filter its `resetValue` — for a\n * page that resets them all in one write, e.g. one URL update. The `resetValue`s still decide when\n * the button shows.\n */\n onClear?: () => void;\n /**\n * Shows \"Clear filters\" while any filter differs from its `resetValue`. It hands each of those\n * filters its `resetValue` back through its own `onValueChange`, or calls `onClear`.\n */\n showClear?: boolean;\n /** Shows the filter icon at the start of the bar. Desktop only. */\n showIcon?: boolean;\n /** `loading`: while the page's data loads, the filters can't be opened, removed or cleared. The search stays usable. */\n state?: 'loading';\n}\n\nconst toggle = (set: ReadonlySet<string>, id: string, isIn: boolean) => {\n if (set.has(id) === isIn) return set;\n const next = new Set(set);\n if (isIn) next.add(id);\n else next.delete(id);\n return next;\n};\n\n/**\n * A bar of filters above a list. Each filter is a controlled sub-component with its own `value` and\n * `onValueChange`; the bar lays them out and offers \"Clear filters\" across all of them.\n *\n * Below the tablet breakpoint the bar collapses into a \"Filters\" button opening a full-screen dialog,\n * where every filter is a field opening its own view. A filter still applies on its view's \"Apply\".\n */\nconst BitkitFilter = forwardRef<HTMLDivElement, BitkitFilterProps>((props, ref) => {\n const {\n children,\n contentAlign,\n contentWidth,\n css,\n device,\n onClear,\n showClear = true,\n showIcon = true,\n state,\n ...rest\n } = props;\n const { isMobile: isMobileViewport } = useResponsive();\n const isMobile = device ? device === 'mobile' : isMobileViewport;\n const isDisabled = state === 'loading';\n const { disablePortal } = usePortalContext();\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n const recipe = useSlotRecipe({ key: 'filter' });\n let pageLayout: 'capped' | 'full' | undefined;\n if (contentWidth) pageLayout = contentWidth === 'full' ? 'full' : 'capped';\n const styles = recipe({ contentAlign: pageLayout === 'capped' ? contentAlign : undefined, pageLayout });\n\n const resets = useRef(new Map<string, () => void>());\n const [dirtyIds, setDirtyIds] = useState<ReadonlySet<string>>(new Set());\n const [activeIds, setActiveIds] = useState<ReadonlySet<string>>(new Set());\n\n const register = useCallback((id: string, reset: () => void) => {\n resets.current.set(id, reset);\n }, []);\n\n const setStatus = useCallback((id: string, { isActive, isDirty }: FilterStatus) => {\n setDirtyIds((prev) => toggle(prev, id, isDirty));\n setActiveIds((prev) => toggle(prev, id, isActive));\n }, []);\n\n const unregister = useCallback(\n (id: string) => {\n resets.current.delete(id);\n setStatus(id, { isActive: false, isDirty: false });\n },\n [setStatus],\n );\n\n const context = useMemo(\n () => ({ isDisabled, isMobile, register, setStatus, styles, unregister }),\n [isDisabled, isMobile, register, setStatus, styles, unregister],\n );\n\n const filters: ReactNode[] = [];\n const searches: ReactNode[] = [];\n // Flattened, so a filter grouped in a fragment is still sorted to the right place.\n flattenChildren(children).forEach((child) => {\n if (child.type === BitkitFilterSearch) searches.push(child);\n else filters.push(child);\n });\n\n const isDirty = dirtyIds.size > 0;\n const activeCount = activeIds.size;\n // The \"Clear filters\" button goes away (or is disabled) once nothing differs, so focus then moves\n // to the first control of the cleared filters rather than dropping to the page. Only if it hasn't\n // gone anywhere else meanwhile, e.g. while a slow reset was under way.\n const focusTarget = useRef<HTMLDivElement>(null);\n const isFocusPending = useRef(false);\n const clearAll = () => {\n if (isDisabled) return;\n isFocusPending.current = true;\n // Called off once focus lands anywhere, so a clear that never fully lands can't pull it in later.\n document.addEventListener(\n 'focusin',\n () => {\n isFocusPending.current = false;\n },\n { once: true },\n );\n if (onClear) onClear();\n else dirtyIds.forEach((id) => resets.current.get(id)?.());\n };\n useEffect(() => {\n if (!isFocusPending.current || isDirty) return;\n isFocusPending.current = false;\n const active = document.activeElement;\n if (active && active !== document.body && !active.matches('[data-filter-clear]')) return;\n focusTarget.current?.querySelector<HTMLElement>('button:not(:disabled), input:not(:disabled)')?.focus();\n }, [isDirty]);\n\n // While the page loads, the controls are only `aria-disabled`, so they keep a focus handed to them.\n // `data-disabled` takes them out of the hover and active styles too.\n const disabledProps = { 'aria-disabled': isDisabled || undefined, 'data-disabled': isDisabled ? '' : undefined };\n const clearProps = { ...disabledProps, 'data-filter-clear': '', onClick: clearAll };\n\n if (isMobile) {\n return (\n <FilterContextProvider value={context}>\n <Box css={css} ref={ref} {...rest}>\n <Box css={styles.mobileBar} ref={isDialogOpen ? undefined : focusTarget}>\n <chakra.button\n aria-expanded={isDialogOpen}\n aria-haspopup=\"dialog\"\n aria-label={`Filters, ${activeCount} applied`}\n {...disabledProps}\n css={styles.mobileTrigger}\n onClick={() => !isDisabled && setIsDialogOpen(true)}\n type=\"button\"\n >\n <IconFilter size=\"16\" />\n Filters\n <BitkitBadge colorVariant={activeCount ? 'purple' : 'neutral'}>{activeCount}</BitkitBadge>\n </chakra.button>\n {showClear && isDirty && (\n <BitkitButton {...clearProps} icon={IconCross} size=\"sm\" variant=\"tertiary\">\n Clear filters\n </BitkitButton>\n )}\n </Box>\n {searches}\n {/* Kept mounted while closed: the filters inside register their values with the bar. */}\n <Drawer.Root\n lazyMount={false}\n onOpenChange={({ open }) => setIsDialogOpen(open)}\n open={isDialogOpen}\n unmountOnExit={false}\n >\n <Portal disabled={disablePortal}>\n <Drawer.Positioner>\n <Drawer.Content>\n <Box css={styles.mobileHeader}>\n <Drawer.Title css={styles.mobileTitle} unstyled>\n Filters\n </Drawer.Title>\n <Drawer.CloseTrigger asChild unstyled>\n <BitkitCloseButton size=\"sm\" />\n </Drawer.CloseTrigger>\n </Box>\n <Drawer.Body css={styles.mobileBody} ref={isDialogOpen ? focusTarget : undefined}>\n {filters}\n </Drawer.Body>\n <Drawer.Footer>\n <Box css={styles.mobileFooter}>\n {showClear && (\n <BitkitButton\n {...clearProps}\n size=\"md\"\n state={isDirty ? undefined : 'disabled'}\n variant=\"secondary\"\n >\n Clear filters\n </BitkitButton>\n )}\n <BitkitButton onClick={() => setIsDialogOpen(false)} size=\"md\">\n Show results\n </BitkitButton>\n </Box>\n </Drawer.Footer>\n </Drawer.Content>\n </Drawer.Positioner>\n </Portal>\n </Drawer.Root>\n </Box>\n </FilterContextProvider>\n );\n }\n\n return (\n <FilterContextProvider value={context}>\n <Box css={[styles.root, css]} ref={ref} {...rest}>\n <Box css={styles.content} maxWidth={contentWidth === 'full' ? undefined : contentWidth} ref={focusTarget}>\n <Box css={styles.filters}>\n {/* In the wrapping row with the filters, so a second row starts under the icon, not beside it. */}\n <Box css={styles.items}>\n {showIcon && (\n <Box css={styles.icon}>\n <IconFilter />\n </Box>\n )}\n {filters}\n </Box>\n {showClear && isDirty && (\n <BitkitButton {...clearProps} flexShrink=\"0\" icon={IconCross} size=\"sm\" variant=\"tertiary\">\n Clear filters\n </BitkitButton>\n )}\n </Box>\n {searches.length > 0 && <Box css={styles.searchBlock}>{searches}</Box>}\n </Box>\n </Box>\n </FilterContextProvider>\n );\n});\n\nBitkitFilter.displayName = 'BitkitFilter';\n\nexport default withSubComponents(BitkitFilter, {\n Add: BitkitFilterAdd,\n DateRange: BitkitFilterDateRange,\n Search: BitkitFilterSearch,\n Select: BitkitFilterSelect,\n Switch: BitkitFilterSwitch,\n});\n"],"mappings":"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"}
@@ -148,7 +148,6 @@ var FilterSelectForm = (props) => {
148
148
  });
149
149
  else if (showSearch) search = /* @__PURE__ */ jsx(Box, {
150
150
  css: styles.popoverSearch,
151
- "data-filter-search": "",
152
151
  children: /* @__PURE__ */ jsx(BitkitSearchInput, {
153
152
  label: searchLabel,
154
153
  onChange: onSearchTextChange,
@@ -1 +1 @@
1
- {"version":3,"file":"FilterSelectForm.js","names":["_Fragment","BitkitList"],"sources":["../../../../lib/components/BitkitFilter/components/FilterSelectForm.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { createListCollection } from '@chakra-ui/react/collection';\nimport { Listbox } from '@chakra-ui/react/listbox';\nimport { HStack } from '@chakra-ui/react/stack';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { Fragment, type ReactNode, useEffect, useId, useMemo, useRef, useState } from 'react';\n\nimport { type BitkitIconComponent, IconCheck } from '../../../icons';\nimport { type BitkitColorToken } from '../../../theme/themeUtils';\nimport BitkitCheckbox from '../../BitkitCheckbox/BitkitCheckbox';\nimport BitkitCheckboxGroup from '../../BitkitCheckboxGroup/BitkitCheckboxGroup';\nimport BitkitGroupHeading from '../../BitkitGroupHeading/BitkitGroupHeading';\nimport BitkitInlineLoading from '../../BitkitInlineLoading/BitkitInlineLoading';\nimport BitkitList from '../../BitkitList/BitkitList';\nimport BitkitSearchInput from '../../BitkitSearchInput/BitkitSearchInput';\nimport BitkitTextInput from '../../BitkitTextInput/BitkitTextInput';\nimport { useFilterContext } from '../BitkitFilter.context';\nimport { compilePattern, isEqualFilterValue, isPattern, toRunningText } from '../BitkitFilter.utils';\nimport { FilterPanelFooter, FilterPanelHeader } from './FilterPanel';\nimport FilterSearchInput from './FilterSearchInput';\n\nexport interface BitkitFilterSelectItem {\n /**\n * Lists the option under this heading, with the others of the same group. Only the open list shows\n * it: the chip shows the label alone, so the label has to make sense without its group.\n */\n group?: string;\n icon?: BitkitIconComponent;\n /** Colors the icon, e.g. a status: `icon/positive` for \"Passed\". */\n iconColor?: BitkitColorToken<'icon'>;\n label: string;\n /** Unique across all groups. */\n value: string;\n}\n\n/**\n * Gathers the options by `group`, so the list (and its keyboard order) runs group by group. The groups\n * keep their order in `items`, with the ungrouped options (an empty-named group) first; within a\n * group the options keep their order in `options`, e.g. the applied ones first.\n */\nconst groupItems = (options: BitkitFilterSelectItem[], items: BitkitFilterSelectItem[]) => {\n const groups = new Map<string, BitkitFilterSelectItem[]>([['', []]]);\n [...items, ...options].forEach((item) => {\n if (!groups.has(item.group ?? '')) groups.set(item.group ?? '', []);\n });\n options.forEach((option) => groups.get(option.group ?? '')?.push(option));\n return [...groups].filter(([, groupOptions]) => groupOptions.length);\n};\n\n/** The list renders at most this many options; search narrows down the rest. */\nexport const MAX_VISIBLE_ITEMS = 100;\n\n/** Below this many options the list is short enough to scan, so there is no search input. */\nconst SEARCH_THRESHOLD = 5;\n\nexport interface FilterSelectFormProps {\n /** The filter holds a value: the footer offers \"Clear\" instead of the wildcard-mode switch. */\n isEditing: boolean;\n /** Keeps `items` in their own order instead of listing the applied ones first — for a switch's fixed options. */\n isOrderFixed?: boolean;\n /** A value is always applied: no \"Clear\" in the footer. */\n isRequired?: boolean;\n items: BitkitFilterSelectItem[];\n label: string;\n loading?: boolean;\n loadingLabel?: string;\n multiple?: boolean;\n onApply: (value: string[]) => void;\n onCancel: () => void;\n onSearchChange?: (searchText: string) => void;\n pattern?: boolean;\n pluralLabel: string;\n searchPlaceholder?: string;\n /**\n * The applied selection with its labels. Without a search, any of it missing from `items` — e.g.\n * left behind by a server search — is listed first, so it can still be unchecked.\n */\n selectedItems?: BitkitFilterSelectItem[];\n value: string[];\n}\n\n/** The body of a select filter's panel: search, the option list or wildcard pattern, and the footer. */\nconst FilterSelectForm = (props: FilterSelectFormProps) => {\n const {\n isEditing,\n isOrderFixed,\n isRequired,\n items,\n label,\n loading,\n loadingLabel = 'Loading...',\n multiple,\n onApply,\n onCancel,\n onSearchChange,\n pattern,\n pluralLabel,\n searchPlaceholder = 'Search for options',\n selectedItems = [],\n value,\n } = props;\n const { isMobile, styles } = useFilterContext();\n\n const [draft, setDraft] = useState(value);\n const [mode, setMode] = useState<'list' | 'pattern'>(pattern && value[0] && isPattern(value[0]) ? 'pattern' : 'list');\n const [searchText, setSearchText] = useState('');\n // Set once the options have loaded, so a later reload (a search, or clearing it) keeps the search and footer.\n const [hasLoaded, setHasLoaded] = useState(!loading);\n if (!loading && !hasLoaded) setHasLoaded(true);\n\n const onSearchTextChange = (text: string) => {\n setSearchText(text);\n onSearchChange?.(text);\n };\n\n // With `onSearchChange` the consumer filters `items` itself, e.g. on the server. Without a search,\n // the applied options come first. `value` doesn't change while the panel is open, so the order is\n // set when it opens and rows don't jump as options are (un)checked.\n const matchingItems = useMemo(() => {\n if (!searchText) {\n if (isOrderFixed) return items;\n const applied = value.flatMap((selected) => {\n const item = items.find((option) => option.value === selected);\n return item ?? selectedItems.find((option) => option.value === selected) ?? [];\n });\n return [...applied, ...items.filter((item) => !value.includes(item.value))];\n }\n if (onSearchChange) return items;\n const query = searchText.toLowerCase();\n return items.filter((item) => item.label.toLowerCase().includes(query));\n }, [isOrderFixed, items, onSearchChange, searchText, selectedItems, value]);\n\n const visibleGroups = useMemo(\n () => groupItems(matchingItems.slice(0, MAX_VISIBLE_ITEMS), items),\n [items, matchingItems],\n );\n const visibleItems = visibleGroups.flatMap(([, groupItems]) => groupItems);\n // The first load shows only the title and a loading row; later loads keep the input and footer in place.\n const isInitialLoading = !!loading && !hasLoaded;\n const showSearch = !isInitialLoading && (!!onSearchChange || items.length > SEARCH_THRESHOLD);\n const searchLabel = `Search ${toRunningText(pluralLabel)}`;\n const showLimitHelper = matchingItems.length > MAX_VISIBLE_ITEMS;\n\n const patternValue = draft[0] ?? '';\n const isApplyDisabled =\n isEqualFilterValue(draft, value) ||\n (mode === 'pattern' && !(patternValue && isPattern(patternValue))) ||\n (!!isRequired && !draft.length);\n\n // Switching between the list and the pattern moves focus into the new view, so typing goes there.\n const bodyRef = useRef<HTMLDivElement>(null);\n const hasSwitchedMode = useRef(false);\n useEffect(() => {\n if (!hasSwitchedMode.current) return;\n bodyRef.current\n ?.querySelector<HTMLElement>('input:not([type=hidden]), [role=listbox], input[type=checkbox]')\n ?.focus();\n }, [mode]);\n\n let start;\n if (isEditing && !isRequired) {\n start = { label: multiple && isMobile ? 'Clear all' : 'Clear', onClick: () => onApply([]) };\n } else if (pattern && !isEditing) {\n start = {\n label: mode === 'list' ? 'Use wildcard pattern' : 'Select from list',\n onClick: () => {\n hasSwitchedMode.current = true;\n setMode(mode === 'list' ? 'pattern' : 'list');\n setDraft([]);\n },\n };\n }\n\n let list;\n if (loading) {\n list = <BitkitInlineLoading css={styles.loading} label={loadingLabel} size={isMobile ? 'lg' : 'md'} />;\n } else if (!visibleItems.length) {\n list = (\n <Text css={styles.loading} color=\"text/secondary\" textStyle={isMobile ? 'body/lg/regular' : 'body/md/regular'}>\n {searchText ? 'No result. Refine your search term.' : 'No options available.'}\n </Text>\n );\n } else if (multiple && !isMobile) {\n list = (\n <Box css={styles.checkboxList}>\n <BitkitCheckboxGroup aria-label={label} onValueChange={setDraft} size=\"md\" value={draft}>\n {visibleGroups.map(([group, groupItems]) => {\n const checkboxes = groupItems.map((item) => (\n <BitkitCheckbox\n key={item.value}\n labelText={\n item.icon ? (\n <HStack gap=\"4\">\n <item.icon color={item.iconColor} data-option-icon={item.iconColor ? undefined : ''} size=\"16\" />\n {item.label}\n </HStack>\n ) : (\n item.label\n )\n }\n value={item.value}\n />\n ));\n return group ? (\n <CheckboxOptionGroup key={group} label={group}>\n {checkboxes}\n </CheckboxOptionGroup>\n ) : (\n <Fragment key={group}>{checkboxes}</Fragment>\n );\n })}\n </BitkitCheckboxGroup>\n {showLimitHelper && <LimitHelper marginBlockStart=\"16\" />}\n </Box>\n );\n } else {\n list = (\n <FilterListbox\n groups={visibleGroups}\n items={visibleItems}\n label={label}\n multiple={multiple}\n onValueChange={setDraft}\n showLimitHelper={showLimitHelper}\n value={draft}\n />\n );\n }\n\n let search = null;\n if (showSearch && isMobile) {\n search = (\n <FilterSearchInput\n label={searchLabel}\n onValueChange={onSearchTextChange}\n placeholder={searchPlaceholder}\n value={searchText}\n />\n );\n } else if (showSearch) {\n search = (\n <Box css={styles.popoverSearch} data-filter-search=\"\">\n <BitkitSearchInput\n label={searchLabel}\n onChange={onSearchTextChange}\n placeholder={searchPlaceholder}\n size=\"md\"\n value={searchText}\n />\n </Box>\n );\n }\n\n const body = (\n <Box css={styles.popoverBody} ref={bodyRef}>\n {mode === 'pattern' ? (\n <FilterPatternBody items={items} onValueChange={setDraft} pluralLabel={pluralLabel} value={patternValue} />\n ) : (\n <>\n {search}\n {list}\n </>\n )}\n </Box>\n );\n\n return (\n <>\n <FilterPanelHeader\n count={multiple && mode === 'list' ? draft.length : undefined}\n title={multiple ? pluralLabel : label}\n />\n {isMobile ? (\n <Box flex=\"1\" overflowY=\"auto\">\n {body}\n </Box>\n ) : (\n body\n )}\n {!isInitialLoading && (\n <FilterPanelFooter\n applyLabel={multiple && mode === 'list' && draft.length ? `Apply (${draft.length})` : undefined}\n isApplyDisabled={isApplyDisabled}\n onApply={() => onApply(mode === 'pattern' ? [patternValue] : draft)}\n onCancel={onCancel}\n start={start}\n />\n )}\n </>\n );\n};\n\n/** A named group of the desktop checkboxes, so a screen reader tells which group an option is in. */\nconst CheckboxOptionGroup = ({ children, label }: { children: ReactNode; label: string }) => {\n const headingId = useId();\n\n return (\n // Stacked like the checkbox group's own children, which its flex column no longer reaches in here.\n <Box aria-labelledby={headingId} display=\"flex\" flexDirection=\"column\" gap=\"12\" role=\"group\">\n {/* The list pads 20; the heading lines up 24 from the popover's edge, like the listbox's. */}\n <BitkitGroupHeading id={headingId} label={label} paddingBlockStart=\"12\" paddingInline=\"4\" />\n {children}\n </Box>\n );\n};\n\nconst LimitHelper = ({ marginBlockStart }: { marginBlockStart?: '16' }) => {\n const { styles } = useFilterContext();\n\n return (\n <Text css={styles.listHelperText} marginBlockStart={marginBlockStart}>\n Showing the first {MAX_VISIBLE_ITEMS} options. Search to find more.\n </Text>\n );\n};\n\ninterface FilterListboxProps {\n groups: [string, BitkitFilterSelectItem[]][];\n /** `groups` flattened, in the same order: the collection's (and so the keyboard's) order. */\n items: BitkitFilterSelectItem[];\n label: string;\n multiple?: boolean;\n onValueChange: (value: string[]) => void;\n showLimitHelper: boolean;\n value: string[];\n}\n\n/**\n * The option list for a single select, and on mobile for a multiple one too — there the rows are\n * full-width and highlighted when selected, with a checkbox drawn in front.\n */\nconst FilterListbox = (props: FilterListboxProps) => {\n const { groups, items, label, multiple, onValueChange, showLimitHelper, value } = props;\n const { isMobile, styles } = useFilterContext();\n const collection = useMemo(() => createListCollection({ items }), [items]);\n const checkboxStyles = useSlotRecipe({ key: 'checkbox' })({ size: 'lg' });\n\n const checkIndicator = (\n <Listbox.ItemIndicator>\n <IconCheck size=\"16\" />\n </Listbox.ItemIndicator>\n );\n\n const renderItem = (item: BitkitFilterSelectItem) => {\n const state = value.includes(item.value) ? 'checked' : 'unchecked';\n const check = multiple ? (\n // Drawn, not a real checkbox: the option row is the control, and a nested input would be a second one.\n <Box aria-hidden css={[checkboxStyles.control, styles.mobileListCheckbox]} data-state={state}>\n <IconCheck />\n </Box>\n ) : (\n <Box aria-hidden css={styles.mobileListCheck} data-state={state}>\n <IconCheck size=\"16\" />\n </Box>\n );\n return (\n <Listbox.Item item={item} key={item.value}>\n {isMobile && check}\n {!!item.icon && (\n <item.icon\n color={item.iconColor}\n // Without an `iconColor` of its own, the icon follows the row's state.\n data-option-icon={item.iconColor ? undefined : ''}\n size={isMobile ? '24' : '16'}\n />\n )}\n <Listbox.ItemText>{item.label}</Listbox.ItemText>\n {!isMobile && checkIndicator}\n </Listbox.Item>\n );\n };\n\n return (\n <Listbox.Root\n collection={collection}\n onValueChange={(details) => onValueChange(details.value)}\n selectionMode={multiple ? 'multiple' : 'single'}\n size={isMobile ? 'lg' : 'md'}\n value={value}\n >\n {/* Zag points the content's aria-labelledby at the label, so it has to exist. */}\n <Listbox.Label srOnly>{label}</Listbox.Label>\n <Listbox.Content>\n {/* Ungrouped options sit straight in the list: a group around them would have no name. */}\n {groups.map(([group, groupItems]) =>\n group ? (\n <Listbox.ItemGroup key={group}>\n <Listbox.ItemGroupLabel asChild>\n <BitkitGroupHeading label={group} paddingBlockStart=\"12\" paddingInline=\"24\" />\n </Listbox.ItemGroupLabel>\n {groupItems.map(renderItem)}\n </Listbox.ItemGroup>\n ) : (\n groupItems.map(renderItem)\n ),\n )}\n </Listbox.Content>\n {/* Outside the content, whose `listbox` role allows only options and groups. */}\n {showLimitHelper && (\n <Box paddingBlockStart=\"8\" paddingInline=\"24\">\n <LimitHelper />\n </Box>\n )}\n </Listbox.Root>\n );\n};\n\ninterface FilterPatternBodyProps {\n items: BitkitFilterSelectItem[];\n onValueChange: (value: string[]) => void;\n pluralLabel: string;\n value: string;\n}\n\nconst FilterPatternBody = ({ items, onValueChange, pluralLabel, value }: FilterPatternBodyProps) => {\n const { isMobile, styles } = useFilterContext();\n const noun = toRunningText(pluralLabel);\n const matches = useMemo(() => {\n if (!isPattern(value)) return null;\n const regExp = compilePattern(value);\n return items.filter((item) => !isPattern(item.label) && regExp.test(item.label));\n }, [items, value]);\n\n let results;\n if (!matches) {\n results = (\n <Text color=\"text/secondary\" textStyle=\"body/md/regular\">\n Enter a pattern with the wildcard &lsquo;*&rsquo; to view {noun} with matching names.\n </Text>\n );\n } else if (!matches.length) {\n results = (\n <Text color=\"text/tertiary\" textStyle=\"body/md/regular\">\n (no matching {noun})\n </Text>\n );\n } else {\n results = (\n <>\n <BitkitList size=\"md\">\n {matches.slice(0, MAX_VISIBLE_ITEMS).map((item) => (\n <BitkitList.Item key={item.value}>{item.label}</BitkitList.Item>\n ))}\n </BitkitList>\n {matches.length > MAX_VISIBLE_ITEMS && (\n <Text css={styles.listHelperText} marginBlockStart=\"16\">\n Showing the first {MAX_VISIBLE_ITEMS} matches.\n </Text>\n )}\n </>\n );\n }\n\n return (\n <Box css={styles.pattern} data-filter-pattern=\"\">\n <BitkitTextInput\n helperText=\"Allowed wildcard character: *\"\n label=\"Wildcard pattern\"\n onValueChange={(text) => onValueChange(text ? [text] : [])}\n placeholder=\"(e.g. *main*, release-*)\"\n size={isMobile ? 'lg' : 'md'}\n value={value}\n />\n <Box css={styles.patternResults}>\n <Text css={styles.patternResultsLabel}>Matching results{matches?.length ? ` (${matches.length})` : ''}</Text>\n {results}\n </Box>\n </Box>\n );\n};\n\nexport default FilterSelectForm;\n"],"mappings":"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"}
1
+ {"version":3,"file":"FilterSelectForm.js","names":["_Fragment","BitkitList"],"sources":["../../../../lib/components/BitkitFilter/components/FilterSelectForm.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { createListCollection } from '@chakra-ui/react/collection';\nimport { Listbox } from '@chakra-ui/react/listbox';\nimport { HStack } from '@chakra-ui/react/stack';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { Fragment, type ReactNode, useEffect, useId, useMemo, useRef, useState } from 'react';\n\nimport { type BitkitIconComponent, IconCheck } from '../../../icons';\nimport { type BitkitColorToken } from '../../../theme/themeUtils';\nimport BitkitCheckbox from '../../BitkitCheckbox/BitkitCheckbox';\nimport BitkitCheckboxGroup from '../../BitkitCheckboxGroup/BitkitCheckboxGroup';\nimport BitkitGroupHeading from '../../BitkitGroupHeading/BitkitGroupHeading';\nimport BitkitInlineLoading from '../../BitkitInlineLoading/BitkitInlineLoading';\nimport BitkitList from '../../BitkitList/BitkitList';\nimport BitkitSearchInput from '../../BitkitSearchInput/BitkitSearchInput';\nimport BitkitTextInput from '../../BitkitTextInput/BitkitTextInput';\nimport { useFilterContext } from '../BitkitFilter.context';\nimport { compilePattern, isEqualFilterValue, isPattern, toRunningText } from '../BitkitFilter.utils';\nimport { FilterPanelFooter, FilterPanelHeader } from './FilterPanel';\nimport FilterSearchInput from './FilterSearchInput';\n\nexport interface BitkitFilterSelectItem {\n /**\n * Lists the option under this heading, with the others of the same group. Only the open list shows\n * it: the chip shows the label alone, so the label has to make sense without its group.\n */\n group?: string;\n icon?: BitkitIconComponent;\n /** Colors the icon, e.g. a status: `icon/positive` for \"Passed\". */\n iconColor?: BitkitColorToken<'icon'>;\n label: string;\n /** Unique across all groups. */\n value: string;\n}\n\n/**\n * Gathers the options by `group`, so the list (and its keyboard order) runs group by group. The groups\n * keep their order in `items`, with the ungrouped options (an empty-named group) first; within a\n * group the options keep their order in `options`, e.g. the applied ones first.\n */\nconst groupItems = (options: BitkitFilterSelectItem[], items: BitkitFilterSelectItem[]) => {\n const groups = new Map<string, BitkitFilterSelectItem[]>([['', []]]);\n [...items, ...options].forEach((item) => {\n if (!groups.has(item.group ?? '')) groups.set(item.group ?? '', []);\n });\n options.forEach((option) => groups.get(option.group ?? '')?.push(option));\n return [...groups].filter(([, groupOptions]) => groupOptions.length);\n};\n\n/** The list renders at most this many options; search narrows down the rest. */\nexport const MAX_VISIBLE_ITEMS = 100;\n\n/** Below this many options the list is short enough to scan, so there is no search input. */\nconst SEARCH_THRESHOLD = 5;\n\nexport interface FilterSelectFormProps {\n /** The filter holds a value: the footer offers \"Clear\" instead of the wildcard-mode switch. */\n isEditing: boolean;\n /** Keeps `items` in their own order instead of listing the applied ones first — for a switch's fixed options. */\n isOrderFixed?: boolean;\n /** A value is always applied: no \"Clear\" in the footer. */\n isRequired?: boolean;\n items: BitkitFilterSelectItem[];\n label: string;\n loading?: boolean;\n loadingLabel?: string;\n multiple?: boolean;\n onApply: (value: string[]) => void;\n onCancel: () => void;\n onSearchChange?: (searchText: string) => void;\n pattern?: boolean;\n pluralLabel: string;\n searchPlaceholder?: string;\n /**\n * The applied selection with its labels. Without a search, any of it missing from `items` — e.g.\n * left behind by a server search — is listed first, so it can still be unchecked.\n */\n selectedItems?: BitkitFilterSelectItem[];\n value: string[];\n}\n\n/** The body of a select filter's panel: search, the option list or wildcard pattern, and the footer. */\nconst FilterSelectForm = (props: FilterSelectFormProps) => {\n const {\n isEditing,\n isOrderFixed,\n isRequired,\n items,\n label,\n loading,\n loadingLabel = 'Loading...',\n multiple,\n onApply,\n onCancel,\n onSearchChange,\n pattern,\n pluralLabel,\n searchPlaceholder = 'Search for options',\n selectedItems = [],\n value,\n } = props;\n const { isMobile, styles } = useFilterContext();\n\n const [draft, setDraft] = useState(value);\n const [mode, setMode] = useState<'list' | 'pattern'>(pattern && value[0] && isPattern(value[0]) ? 'pattern' : 'list');\n const [searchText, setSearchText] = useState('');\n // Set once the options have loaded, so a later reload (a search, or clearing it) keeps the search and footer.\n const [hasLoaded, setHasLoaded] = useState(!loading);\n if (!loading && !hasLoaded) setHasLoaded(true);\n\n const onSearchTextChange = (text: string) => {\n setSearchText(text);\n onSearchChange?.(text);\n };\n\n // With `onSearchChange` the consumer filters `items` itself, e.g. on the server. Without a search,\n // the applied options come first. `value` doesn't change while the panel is open, so the order is\n // set when it opens and rows don't jump as options are (un)checked.\n const matchingItems = useMemo(() => {\n if (!searchText) {\n if (isOrderFixed) return items;\n const applied = value.flatMap((selected) => {\n const item = items.find((option) => option.value === selected);\n return item ?? selectedItems.find((option) => option.value === selected) ?? [];\n });\n return [...applied, ...items.filter((item) => !value.includes(item.value))];\n }\n if (onSearchChange) return items;\n const query = searchText.toLowerCase();\n return items.filter((item) => item.label.toLowerCase().includes(query));\n }, [isOrderFixed, items, onSearchChange, searchText, selectedItems, value]);\n\n const visibleGroups = useMemo(\n () => groupItems(matchingItems.slice(0, MAX_VISIBLE_ITEMS), items),\n [items, matchingItems],\n );\n const visibleItems = visibleGroups.flatMap(([, groupItems]) => groupItems);\n // The first load shows only the title and a loading row; later loads keep the input and footer in place.\n const isInitialLoading = !!loading && !hasLoaded;\n const showSearch = !isInitialLoading && (!!onSearchChange || items.length > SEARCH_THRESHOLD);\n const searchLabel = `Search ${toRunningText(pluralLabel)}`;\n const showLimitHelper = matchingItems.length > MAX_VISIBLE_ITEMS;\n\n const patternValue = draft[0] ?? '';\n const isApplyDisabled =\n isEqualFilterValue(draft, value) ||\n (mode === 'pattern' && !(patternValue && isPattern(patternValue))) ||\n (!!isRequired && !draft.length);\n\n // Switching between the list and the pattern moves focus into the new view, so typing goes there.\n const bodyRef = useRef<HTMLDivElement>(null);\n const hasSwitchedMode = useRef(false);\n useEffect(() => {\n if (!hasSwitchedMode.current) return;\n bodyRef.current\n ?.querySelector<HTMLElement>('input:not([type=hidden]), [role=listbox], input[type=checkbox]')\n ?.focus();\n }, [mode]);\n\n let start;\n if (isEditing && !isRequired) {\n start = { label: multiple && isMobile ? 'Clear all' : 'Clear', onClick: () => onApply([]) };\n } else if (pattern && !isEditing) {\n start = {\n label: mode === 'list' ? 'Use wildcard pattern' : 'Select from list',\n onClick: () => {\n hasSwitchedMode.current = true;\n setMode(mode === 'list' ? 'pattern' : 'list');\n setDraft([]);\n },\n };\n }\n\n let list;\n if (loading) {\n list = <BitkitInlineLoading css={styles.loading} label={loadingLabel} size={isMobile ? 'lg' : 'md'} />;\n } else if (!visibleItems.length) {\n list = (\n <Text css={styles.loading} color=\"text/secondary\" textStyle={isMobile ? 'body/lg/regular' : 'body/md/regular'}>\n {searchText ? 'No result. Refine your search term.' : 'No options available.'}\n </Text>\n );\n } else if (multiple && !isMobile) {\n list = (\n <Box css={styles.checkboxList}>\n <BitkitCheckboxGroup aria-label={label} onValueChange={setDraft} size=\"md\" value={draft}>\n {visibleGroups.map(([group, groupItems]) => {\n const checkboxes = groupItems.map((item) => (\n <BitkitCheckbox\n key={item.value}\n labelText={\n item.icon ? (\n <HStack gap=\"4\">\n <item.icon color={item.iconColor} data-option-icon={item.iconColor ? undefined : ''} size=\"16\" />\n {item.label}\n </HStack>\n ) : (\n item.label\n )\n }\n value={item.value}\n />\n ));\n return group ? (\n <CheckboxOptionGroup key={group} label={group}>\n {checkboxes}\n </CheckboxOptionGroup>\n ) : (\n <Fragment key={group}>{checkboxes}</Fragment>\n );\n })}\n </BitkitCheckboxGroup>\n {showLimitHelper && <LimitHelper marginBlockStart=\"16\" />}\n </Box>\n );\n } else {\n list = (\n <FilterListbox\n groups={visibleGroups}\n items={visibleItems}\n label={label}\n multiple={multiple}\n onValueChange={setDraft}\n showLimitHelper={showLimitHelper}\n value={draft}\n />\n );\n }\n\n let search = null;\n if (showSearch && isMobile) {\n search = (\n <FilterSearchInput\n label={searchLabel}\n onValueChange={onSearchTextChange}\n placeholder={searchPlaceholder}\n value={searchText}\n />\n );\n } else if (showSearch) {\n search = (\n <Box css={styles.popoverSearch}>\n <BitkitSearchInput\n label={searchLabel}\n onChange={onSearchTextChange}\n placeholder={searchPlaceholder}\n size=\"md\"\n value={searchText}\n />\n </Box>\n );\n }\n\n const body = (\n <Box css={styles.popoverBody} ref={bodyRef}>\n {mode === 'pattern' ? (\n <FilterPatternBody items={items} onValueChange={setDraft} pluralLabel={pluralLabel} value={patternValue} />\n ) : (\n <>\n {search}\n {list}\n </>\n )}\n </Box>\n );\n\n return (\n <>\n <FilterPanelHeader\n count={multiple && mode === 'list' ? draft.length : undefined}\n title={multiple ? pluralLabel : label}\n />\n {isMobile ? (\n <Box flex=\"1\" overflowY=\"auto\">\n {body}\n </Box>\n ) : (\n body\n )}\n {!isInitialLoading && (\n <FilterPanelFooter\n applyLabel={multiple && mode === 'list' && draft.length ? `Apply (${draft.length})` : undefined}\n isApplyDisabled={isApplyDisabled}\n onApply={() => onApply(mode === 'pattern' ? [patternValue] : draft)}\n onCancel={onCancel}\n start={start}\n />\n )}\n </>\n );\n};\n\n/** A named group of the desktop checkboxes, so a screen reader tells which group an option is in. */\nconst CheckboxOptionGroup = ({ children, label }: { children: ReactNode; label: string }) => {\n const headingId = useId();\n\n return (\n // Stacked like the checkbox group's own children, which its flex column no longer reaches in here.\n <Box aria-labelledby={headingId} display=\"flex\" flexDirection=\"column\" gap=\"12\" role=\"group\">\n {/* The list pads 20; the heading lines up 24 from the popover's edge, like the listbox's. */}\n <BitkitGroupHeading id={headingId} label={label} paddingBlockStart=\"12\" paddingInline=\"4\" />\n {children}\n </Box>\n );\n};\n\nconst LimitHelper = ({ marginBlockStart }: { marginBlockStart?: '16' }) => {\n const { styles } = useFilterContext();\n\n return (\n <Text css={styles.listHelperText} marginBlockStart={marginBlockStart}>\n Showing the first {MAX_VISIBLE_ITEMS} options. Search to find more.\n </Text>\n );\n};\n\ninterface FilterListboxProps {\n groups: [string, BitkitFilterSelectItem[]][];\n /** `groups` flattened, in the same order: the collection's (and so the keyboard's) order. */\n items: BitkitFilterSelectItem[];\n label: string;\n multiple?: boolean;\n onValueChange: (value: string[]) => void;\n showLimitHelper: boolean;\n value: string[];\n}\n\n/**\n * The option list for a single select, and on mobile for a multiple one too — there the rows are\n * full-width and highlighted when selected, with a checkbox drawn in front.\n */\nconst FilterListbox = (props: FilterListboxProps) => {\n const { groups, items, label, multiple, onValueChange, showLimitHelper, value } = props;\n const { isMobile, styles } = useFilterContext();\n const collection = useMemo(() => createListCollection({ items }), [items]);\n const checkboxStyles = useSlotRecipe({ key: 'checkbox' })({ size: 'lg' });\n\n const checkIndicator = (\n <Listbox.ItemIndicator>\n <IconCheck size=\"16\" />\n </Listbox.ItemIndicator>\n );\n\n const renderItem = (item: BitkitFilterSelectItem) => {\n const state = value.includes(item.value) ? 'checked' : 'unchecked';\n const check = multiple ? (\n // Drawn, not a real checkbox: the option row is the control, and a nested input would be a second one.\n <Box aria-hidden css={[checkboxStyles.control, styles.mobileListCheckbox]} data-state={state}>\n <IconCheck />\n </Box>\n ) : (\n <Box aria-hidden css={styles.mobileListCheck} data-state={state}>\n <IconCheck size=\"16\" />\n </Box>\n );\n return (\n <Listbox.Item item={item} key={item.value}>\n {isMobile && check}\n {!!item.icon && (\n <item.icon\n color={item.iconColor}\n // Without an `iconColor` of its own, the icon follows the row's state.\n data-option-icon={item.iconColor ? undefined : ''}\n size={isMobile ? '24' : '16'}\n />\n )}\n <Listbox.ItemText>{item.label}</Listbox.ItemText>\n {!isMobile && checkIndicator}\n </Listbox.Item>\n );\n };\n\n return (\n <Listbox.Root\n collection={collection}\n onValueChange={(details) => onValueChange(details.value)}\n selectionMode={multiple ? 'multiple' : 'single'}\n size={isMobile ? 'lg' : 'md'}\n value={value}\n >\n {/* Zag points the content's aria-labelledby at the label, so it has to exist. */}\n <Listbox.Label srOnly>{label}</Listbox.Label>\n <Listbox.Content>\n {/* Ungrouped options sit straight in the list: a group around them would have no name. */}\n {groups.map(([group, groupItems]) =>\n group ? (\n <Listbox.ItemGroup key={group}>\n <Listbox.ItemGroupLabel asChild>\n <BitkitGroupHeading label={group} paddingBlockStart=\"12\" paddingInline=\"24\" />\n </Listbox.ItemGroupLabel>\n {groupItems.map(renderItem)}\n </Listbox.ItemGroup>\n ) : (\n groupItems.map(renderItem)\n ),\n )}\n </Listbox.Content>\n {/* Outside the content, whose `listbox` role allows only options and groups. */}\n {showLimitHelper && (\n <Box paddingBlockStart=\"8\" paddingInline=\"24\">\n <LimitHelper />\n </Box>\n )}\n </Listbox.Root>\n );\n};\n\ninterface FilterPatternBodyProps {\n items: BitkitFilterSelectItem[];\n onValueChange: (value: string[]) => void;\n pluralLabel: string;\n value: string;\n}\n\nconst FilterPatternBody = ({ items, onValueChange, pluralLabel, value }: FilterPatternBodyProps) => {\n const { isMobile, styles } = useFilterContext();\n const noun = toRunningText(pluralLabel);\n const matches = useMemo(() => {\n if (!isPattern(value)) return null;\n const regExp = compilePattern(value);\n return items.filter((item) => !isPattern(item.label) && regExp.test(item.label));\n }, [items, value]);\n\n let results;\n if (!matches) {\n results = (\n <Text color=\"text/secondary\" textStyle=\"body/md/regular\">\n Enter a pattern with the wildcard &lsquo;*&rsquo; to view {noun} with matching names.\n </Text>\n );\n } else if (!matches.length) {\n results = (\n <Text color=\"text/tertiary\" textStyle=\"body/md/regular\">\n (no matching {noun})\n </Text>\n );\n } else {\n results = (\n <>\n <BitkitList size=\"md\">\n {matches.slice(0, MAX_VISIBLE_ITEMS).map((item) => (\n <BitkitList.Item key={item.value}>{item.label}</BitkitList.Item>\n ))}\n </BitkitList>\n {matches.length > MAX_VISIBLE_ITEMS && (\n <Text css={styles.listHelperText} marginBlockStart=\"16\">\n Showing the first {MAX_VISIBLE_ITEMS} matches.\n </Text>\n )}\n </>\n );\n }\n\n return (\n <Box css={styles.pattern} data-filter-pattern=\"\">\n <BitkitTextInput\n helperText=\"Allowed wildcard character: *\"\n label=\"Wildcard pattern\"\n onValueChange={(text) => onValueChange(text ? [text] : [])}\n placeholder=\"(e.g. *main*, release-*)\"\n size={isMobile ? 'lg' : 'md'}\n value={value}\n />\n <Box css={styles.patternResults}>\n <Text css={styles.patternResultsLabel}>Matching results{matches?.length ? ` (${matches.length})` : ''}</Text>\n {results}\n </Box>\n </Box>\n );\n};\n\nexport default FilterSelectForm;\n"],"mappings":"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"}
@@ -4,6 +4,7 @@ declare const filterSlotRecipe: import('@chakra-ui/react').SlotRecipeDefinition<
4
4
  root: {
5
5
  borderBlockEndWidth: "1";
6
6
  borderColor: "border/regular";
7
+ paddingBlock: "12";
7
8
  paddingInline: {
8
9
  base: "16";
9
10
  tablet: "32";
@@ -14,6 +15,7 @@ declare const filterSlotRecipe: import('@chakra-ui/react').SlotRecipeDefinition<
14
15
  root: {
15
16
  borderBlockEndWidth: "1";
16
17
  borderColor: "border/regular";
18
+ paddingBlock: "12";
17
19
  paddingInlineEnd: {
18
20
  base: "16";
19
21
  tablet: "32";
@@ -108,9 +108,7 @@ var filterSlotRecipe = defineSlotRecipe({
108
108
  root: {
109
109
  background: "background/primary",
110
110
  display: "flex",
111
- justifyContent: "center",
112
- paddingBlock: "12",
113
- paddingInline: "16"
111
+ justifyContent: "center"
114
112
  },
115
113
  content: {
116
114
  alignItems: "flex-start",
@@ -288,10 +286,9 @@ var filterSlotRecipe = defineSlotRecipe({
288
286
  popoverContent: {
289
287
  maxHeight: "min(60vh, var(--available-height, 60vh))",
290
288
  maxWidth: rem(800),
291
- minWidth: "var(--reference-width, 0px)",
289
+ minWidth: "max(var(--reference-width, 0px), 20rem)",
292
290
  width: "max-content",
293
291
  "&:has([data-filter-pattern])": { width: rem(480) },
294
- "&:has([data-filter-search])": { minWidth: "max(var(--reference-width, 0px), 20rem)" },
295
292
  "& [data-scope=listbox][data-part=content]": { paddingBlockEnd: 0 }
296
293
  },
297
294
  addMenu: {
@@ -424,8 +421,7 @@ var filterSlotRecipe = defineSlotRecipe({
424
421
  gap: "8",
425
422
  paddingBlockEnd: "16",
426
423
  paddingBlockStart: "24",
427
- paddingInlineEnd: "24",
428
- paddingInlineStart: "16"
424
+ paddingInline: "16"
429
425
  },
430
426
  popoverFooterStart: { flex: "1" },
431
427
  checkboxList: {
@@ -628,6 +624,7 @@ var filterSlotRecipe = defineSlotRecipe({
628
624
  capped: { root: {
629
625
  borderBlockEndWidth: "1",
630
626
  borderColor: "border/regular",
627
+ paddingBlock: "12",
631
628
  paddingInline: {
632
629
  base: "16",
633
630
  tablet: "32"
@@ -636,6 +633,7 @@ var filterSlotRecipe = defineSlotRecipe({
636
633
  full: { root: {
637
634
  borderBlockEndWidth: "1",
638
635
  borderColor: "border/regular",
636
+ paddingBlock: "12",
639
637
  paddingInlineEnd: {
640
638
  base: "16",
641
639
  tablet: "32"
@@ -1 +1 @@
1
- {"version":3,"file":"Filter.recipe.js","names":[],"sources":["../../../lib/theme/slot-recipes/Filter.recipe.ts"],"sourcesContent":["import { defineSlotRecipe, type SystemStyleObject } from '@chakra-ui/react/styled-system';\n\nimport { rem } from '../themeUtils';\n\nconst chipButton: SystemStyleObject = {\n alignItems: 'center',\n alignSelf: 'stretch',\n display: 'flex',\n _hover: {\n background: 'background/hover',\n _active: {\n background: 'background/active',\n },\n },\n _active: {\n background: 'background/active',\n },\n _disabled: {\n cursor: 'not-allowed',\n '& :is(span, svg)': {\n color: 'text/disabled',\n },\n _hover: {\n background: 'transparent',\n },\n },\n};\n\n// The keyboard focus ring for a wrapper whose input has no outline of its own. Chakra's `focusRing`\n// only fires on the focused element itself, so the global ring variables are applied directly.\nconst wrapperFocusRing: SystemStyleObject = {\n outlineColor: 'var(--focus-ring-color)',\n outlineOffset: 'var(--focus-ring-offset)',\n outlineStyle: 'var(--focus-ring-style)',\n outlineWidth: 'var(--focus-ring-width)',\n};\n\nconst switchItemDisabled: SystemStyleObject = {\n color: 'text/disabled',\n cursor: 'not-allowed',\n '& svg': {\n color: 'icon/disabled',\n },\n _hover: {\n background: 'transparent',\n color: 'text/disabled',\n _active: {\n background: 'transparent',\n },\n },\n _active: {\n background: 'transparent',\n },\n _checked: {\n _hover: {\n background: 'background/primary',\n _active: {\n background: 'background/primary',\n },\n },\n _active: {\n background: 'background/primary',\n },\n },\n};\n\nconst filterSlotRecipe = defineSlotRecipe({\n className: 'filter',\n slots: [\n 'root',\n 'content',\n 'filters',\n 'icon',\n 'items',\n 'searchBlock',\n 'search',\n 'searchInput',\n 'switch',\n 'switchItem',\n 'switchItemText',\n 'chip',\n 'chipTrigger',\n 'chipLabel',\n 'chipValue',\n 'chipIcon',\n 'chipChevron',\n 'chipRemove',\n 'popoverContent',\n 'addMenu',\n 'addMenuItem',\n 'addMenuLabel',\n 'addMenuIcon',\n 'addSheetBackdrop',\n 'addSheetPositioner',\n 'addSheet',\n 'addSheetItem',\n 'addSheetItemReason',\n 'calendarFooter',\n 'popoverSearch',\n 'popoverBody',\n 'popoverFooter',\n 'popoverFooterStart',\n 'checkboxList',\n 'listHelperText',\n 'loading',\n 'pattern',\n 'patternResults',\n 'patternResultsLabel',\n 'mobileBar',\n 'mobileTrigger',\n 'mobileSearch',\n 'mobileSearchInput',\n 'mobileHeader',\n 'mobileTitle',\n 'mobilePanelHeader',\n 'mobilePanelOverline',\n 'mobilePanelTitle',\n 'mobileBody',\n 'mobileFooter',\n 'mobileListCheck',\n 'mobileListCheckbox',\n 'field',\n 'fieldLabel',\n 'fieldControl',\n 'fieldTrigger',\n 'fieldIcon',\n 'fieldValue',\n 'fieldChevron',\n 'fieldRemove',\n ],\n base: {\n root: {\n background: 'background/primary',\n display: 'flex',\n justifyContent: 'center',\n paddingBlock: '12',\n paddingInline: '16',\n },\n content: {\n alignItems: 'flex-start',\n display: 'flex',\n flex: '1',\n gap: '16',\n minWidth: 0,\n },\n filters: {\n alignItems: 'flex-start',\n display: 'flex',\n flex: '1',\n gap: '12',\n minWidth: 0,\n paddingBlock: '4',\n },\n icon: {\n color: 'icon/tertiary',\n // Flex, so the inline svg's line box adds no extra height.\n display: 'flex',\n flexShrink: 0,\n padding: '4',\n },\n items: {\n alignItems: 'center',\n display: 'flex',\n flex: '1',\n flexWrap: 'wrap',\n gap: '12',\n minWidth: 0,\n },\n searchBlock: {\n alignSelf: 'stretch',\n borderColor: 'border/minimal',\n borderInlineStartWidth: '1',\n display: 'flex',\n flexShrink: 0,\n paddingInlineStart: '16',\n },\n search: {\n alignItems: 'center',\n background: 'background/primary',\n borderRadius: '4',\n cursor: 'text',\n color: 'icon/tertiary',\n display: 'flex',\n gap: '8',\n height: '40',\n paddingInline: '8',\n width: rem(148),\n _hover: {\n background: 'background/secondary',\n },\n '&:has(input:focus-visible)': wrapperFocusRing,\n },\n searchInput: {\n background: 'transparent',\n color: 'input/text/inputValue',\n flex: '1',\n minWidth: 0,\n outline: 'none',\n textStyle: 'body/md/regular',\n _placeholder: {\n color: 'input/text/placeholder',\n },\n // The clear button replaces the native cancel glyph of `type=\"search\"`.\n '&::-webkit-search-cancel-button': {\n appearance: 'none',\n },\n },\n switch: {\n background: 'background/secondary',\n borderRadius: '4',\n display: 'inline-flex',\n flexShrink: 0,\n position: 'relative',\n },\n switchItem: {\n alignItems: 'center',\n borderRadius: '4',\n color: 'text/secondary',\n cursor: 'pointer',\n display: 'flex',\n gap: '4',\n height: '32',\n paddingInline: '8',\n position: 'relative',\n textStyle: 'body/md/regular',\n whiteSpace: 'nowrap',\n // An item's own `iconColor` is left alone, except when disabled.\n '& svg:not([data-own-color])': {\n color: 'icon/tertiary',\n },\n // Divider after an unselected item, hidden next to the selected or hovered one.\n _after: {\n background: 'border/regular',\n content: '\"\"',\n height: '16',\n insetInlineEnd: 0,\n position: 'absolute',\n top: '8',\n width: '1',\n },\n '&:last-of-type, &[data-state=checked], &:hover, &:has(+ [data-state=checked]), &:has(+ :hover)': {\n _after: {\n display: 'none',\n },\n },\n '&:has(input:focus-visible)': wrapperFocusRing,\n _hover: {\n background: 'background/hover',\n color: 'text/primary',\n '& svg:not([data-own-color])': {\n color: 'icon/secondary',\n },\n _active: {\n background: 'background/active',\n },\n },\n _active: {\n background: 'background/active',\n color: 'text/primary',\n },\n _checked: {\n background: 'background/primary',\n // Inset, so the selected item is no taller than the others.\n boxShadow: 'inset 0 0 0 1px var(--colors-border\\\\/strong)',\n color: 'text/primary',\n '& svg:not([data-own-color])': {\n color: 'icon/secondary',\n },\n _hover: {\n background: 'background/primary',\n },\n },\n // Read-only while the page loads, so the item keeps a focus handed to it; it looks disabled.\n _disabled: switchItemDisabled,\n _readOnly: switchItemDisabled,\n },\n switchItemText: {\n paddingInline: '4',\n },\n chip: {\n alignItems: 'center',\n background: 'background/primary',\n borderColor: 'border/strong',\n borderRadius: '4',\n borderWidth: '1',\n display: 'inline-flex',\n height: '32',\n maxWidth: rem(320),\n minWidth: 0,\n overflow: 'hidden',\n textStyle: 'body/md/regular',\n '&:has(button:is(:disabled, [aria-disabled=true]))': {\n borderColor: 'border/disabled',\n },\n // The chip's popover is open: Zag marks the trigger inside it as expanded.\n '&:has([aria-expanded=true])': {\n boxShadow: '0 0 0 0.125rem var(--focus-ring-color)',\n // Figma's selected chip stays white, even under the pointer that just opened it.\n '& button, & button:hover': {\n background: 'background/primary',\n },\n },\n // The date chip's trigger sits inside the calendar's root and control divs; they stretch like a direct child would.\n '& [data-scope=date-picker]:is([data-part=root], [data-part=control])': {\n alignSelf: 'stretch',\n flex: '1',\n minWidth: 0,\n },\n },\n chipTrigger: {\n ...chipButton,\n flex: '1',\n gap: '4',\n minWidth: 0,\n paddingInlineEnd: '8',\n paddingInlineStart: '12',\n whiteSpace: 'nowrap',\n '&:has([data-chip-icon])': {\n paddingInlineStart: '8',\n },\n '&:is(:hover, :active) [data-chip-icon]': {\n color: 'icon/secondary',\n },\n },\n chipLabel: {\n color: 'text/secondary',\n flexShrink: 0,\n },\n chipValue: {\n color: 'text/body',\n minWidth: 0,\n truncate: true,\n },\n chipIcon: {\n color: 'icon/tertiary',\n flexShrink: 0,\n marginInlineEnd: '4',\n },\n chipChevron: {\n color: 'icon/primary',\n flexShrink: 0,\n marginInlineStart: '8',\n },\n chipRemove: {\n ...chipButton,\n color: 'icon/primary',\n flexShrink: 0,\n paddingInlineEnd: '8',\n paddingInlineStart: '4',\n },\n popoverContent: {\n // The popover's 60vh cap, or less where the space next to the bar is shorter.\n maxHeight: 'min(60vh, var(--available-height, 60vh))',\n // As wide as its content: at least its chip, at most 800px.\n maxWidth: rem(800),\n minWidth: 'var(--reference-width, 0px)',\n width: 'max-content',\n // The wildcard pattern's explanation would otherwise stretch it to its widest.\n '&:has([data-filter-pattern])': {\n width: rem(480),\n },\n // Wide enough for the search's placeholder, which the input's own width doesn't follow.\n '&:has([data-filter-search])': {\n minWidth: 'max(var(--reference-width, 0px), 20rem)',\n },\n // The footer's top padding is the gap under the list, so the list adds none of its own.\n '& [data-scope=listbox][data-part=content]': {\n paddingBlockEnd: 0,\n },\n },\n addMenu: {\n background: 'background/primary',\n borderRadius: '8',\n boxShadow: 'elevation/lg',\n display: 'flex',\n flexDirection: 'column',\n maxHeight: 'var(--available-height)',\n outline: 'none',\n overflowY: 'auto',\n paddingBlock: '8',\n width: rem(240),\n zIndex: 'popover',\n },\n addMenuItem: {\n alignItems: 'center',\n color: 'text/body',\n cursor: 'pointer',\n display: 'flex',\n gap: '4',\n minHeight: '40',\n paddingBlock: '8',\n paddingInline: '16',\n textStyle: 'body/md/regular',\n userSelect: 'none',\n _highlighted: {\n background: 'background/hover',\n _active: {\n background: 'background/active',\n },\n },\n _active: {\n background: 'background/active',\n },\n _disabled: {\n color: 'text/disabled',\n cursor: 'not-allowed',\n _highlighted: {\n background: 'transparent',\n },\n // Not applicable yet: `aria-disabled` but reachable, so the keyboard highlight still shows.\n '&[data-not-applicable]': {\n color: 'text/tertiary',\n _highlighted: {\n background: 'background/hover',\n },\n },\n },\n // The chevron only shows on the row under the pointer or keyboard.\n '&:not([data-highlighted]) [data-add-chevron]': {\n visibility: 'hidden',\n },\n },\n addMenuLabel: {\n color: 'text/tertiary',\n paddingBlock: '8',\n paddingInline: '16',\n textStyle: 'heading/h6',\n },\n addMenuIcon: {\n color: 'icon/tertiary',\n flexShrink: 0,\n marginInlineStart: 'auto',\n },\n addSheetBackdrop: {\n background: 'utilities/overlay-light',\n inset: 0,\n position: 'fixed',\n zIndex: 'calc({zIndex.dialogOverlay} + var(--layer-index, 0))',\n },\n addSheetPositioner: {\n alignItems: 'flex-end',\n display: 'flex',\n inset: 0,\n justifyContent: 'stretch',\n padding: '16',\n position: 'fixed',\n zIndex: 'calc({zIndex.dialog} + var(--layer-index, 0))',\n },\n addSheet: {\n background: 'background/primary',\n borderRadius: '8',\n boxShadow: 'elevation/lg',\n display: 'flex',\n flex: '1',\n flexDirection: 'column',\n maxHeight: '80dvh',\n outline: 'none',\n overflowY: 'auto',\n paddingBlock: '8',\n },\n addSheetItem: {\n ...chipButton,\n alignSelf: 'auto',\n color: 'text/body',\n gap: '12',\n minHeight: '48',\n paddingBlock: '8',\n paddingInline: '16',\n textAlign: 'start',\n textStyle: 'body/lg/regular',\n _disabled: {\n color: 'text/disabled',\n cursor: 'not-allowed',\n _hover: {\n background: 'transparent',\n },\n '&[data-not-applicable]': {\n color: 'text/tertiary',\n '& :is(span, svg)': {\n color: 'text/tertiary',\n },\n },\n },\n },\n addSheetItemReason: {\n color: 'text/tertiary',\n textStyle: 'body/sm/regular',\n },\n calendarFooter: {\n alignItems: 'center',\n display: 'flex',\n gap: '8',\n marginBlockStart: '24',\n },\n popoverSearch: {\n flexShrink: 0,\n paddingBlockEnd: '8',\n paddingBlockStart: '8',\n paddingInline: '12',\n },\n // When the popover is capped by the space available, the list (or pattern results) gives way and\n // scrolls on its own, rather than running under the footer: every part may shrink below its content.\n popoverBody: {\n display: 'flex',\n flexDirection: 'column',\n minHeight: 0,\n '& > *, & [data-scope=listbox]:is([data-part=root], [data-part=content])': {\n minHeight: 0,\n },\n '& [data-scope=listbox][data-part=root]': {\n display: 'flex',\n flexDirection: 'column',\n },\n },\n popoverFooter: {\n alignItems: 'center',\n display: 'flex',\n gap: '8',\n paddingBlockEnd: '16',\n paddingBlockStart: '24',\n paddingInlineEnd: '24',\n paddingInlineStart: '16',\n },\n popoverFooterStart: {\n flex: '1',\n },\n checkboxList: {\n maxHeight: rem(200),\n overflowY: 'auto',\n paddingBlockStart: '8',\n paddingInline: '20',\n // An option's icon: secondary, primary while hovered, interactive once checked.\n '& [data-option-icon]': {\n color: 'icon/secondary',\n },\n '& [data-scope=checkbox][data-part=root]:hover [data-option-icon]': {\n color: 'icon/primary',\n },\n '& [data-scope=checkbox][data-part=root][data-state=checked] [data-option-icon]': {\n color: 'icon/interactive',\n },\n },\n listHelperText: {\n color: 'text/secondary',\n textStyle: 'body/sm/regular',\n },\n loading: {\n paddingBlock: '8',\n paddingInline: '16',\n },\n pattern: {\n display: 'flex',\n flexDirection: 'column',\n gap: '24',\n paddingBlockStart: '8',\n paddingInline: '16',\n },\n patternResults: {\n display: 'flex',\n flexDirection: 'column',\n gap: '8',\n maxHeight: rem(176),\n minHeight: 0,\n overflowY: 'auto',\n },\n patternResultsLabel: {\n color: 'text/primary',\n textStyle: 'comp/input/label',\n },\n mobileBar: {\n alignItems: 'center',\n borderBlockEndWidth: '1',\n borderColor: 'border/minimal',\n display: 'flex',\n gap: '12',\n justifyContent: 'space-between',\n padding: '16',\n },\n mobileTrigger: {\n ...chipButton,\n alignSelf: 'auto',\n background: 'background/primary',\n borderColor: 'border/strong',\n borderRadius: '4',\n borderWidth: '1',\n color: 'text/primary',\n gap: '8',\n height: '32',\n paddingInline: '8',\n textStyle: 'comp/button/sm',\n _icon: {\n color: 'icon/primary',\n },\n _disabled: {\n borderColor: 'border/disabled',\n color: 'text/disabled',\n _icon: {\n color: 'icon/disabled',\n },\n },\n },\n mobileSearch: {\n alignItems: 'center',\n borderBlockEndWidth: '1',\n borderColor: 'border/minimal',\n cursor: 'text',\n color: 'icon/tertiary',\n display: 'flex',\n gap: '12',\n height: rem(56),\n paddingInline: '16',\n // Drawn inside, since the row runs edge to edge.\n '&:has(input:focus-visible)': {\n ...wrapperFocusRing,\n outlineOffset: 'calc(var(--focus-ring-width) * -1)',\n },\n },\n mobileSearchInput: {\n background: 'transparent',\n color: 'input/text/inputValue',\n flex: '1',\n minWidth: 0,\n outline: 'none',\n textStyle: 'body/lg/regular',\n _placeholder: {\n color: 'input/text/placeholder',\n },\n '&::-webkit-search-cancel-button': {\n appearance: 'none',\n },\n },\n mobileHeader: {\n alignItems: 'center',\n borderBlockEndWidth: '1',\n borderColor: 'border/minimal',\n display: 'flex',\n flexShrink: 0,\n gap: '12',\n // Matches the docked drawer's body and footer inset.\n paddingBlock: '16',\n paddingInline: { base: '16', tablet: '24' },\n },\n mobileTitle: {\n color: 'text/primary',\n flex: '1',\n textStyle: 'heading/mobile/h2',\n },\n mobilePanelHeader: {\n alignItems: 'center',\n borderBlockEndWidth: '1',\n borderColor: 'border/minimal',\n display: 'flex',\n flexShrink: 0,\n gap: '12',\n paddingBlock: '12',\n // Matches the docked drawer's footer inset.\n paddingInline: { base: '16', tablet: '24' },\n },\n mobilePanelOverline: {\n color: 'text/tertiary',\n textStyle: 'heading/h6',\n },\n mobilePanelTitle: {\n color: 'text/primary',\n textStyle: 'heading/mobile/h3',\n },\n // The docked drawer pads the body and footer itself.\n mobileBody: {\n display: 'flex',\n flexDirection: 'column',\n gap: '16',\n },\n mobileFooter: {\n display: 'flex',\n gap: '12',\n '& > *': {\n flex: '1',\n },\n },\n // Drawn in front of the label on mobile, with its column kept on unselected rows so the labels line up.\n mobileListCheck: {\n color: 'icon/interactive',\n display: 'flex',\n flexShrink: 0,\n '&[data-state=unchecked]': {\n visibility: 'hidden',\n },\n },\n mobileListCheckbox: {\n flexShrink: 0,\n },\n field: {\n display: 'flex',\n flexDirection: 'column',\n gap: '8',\n },\n fieldLabel: {\n color: 'text/primary',\n textStyle: 'comp/input/label',\n },\n fieldControl: {\n background: 'background/primary',\n borderColor: 'border/strong',\n borderRadius: '4',\n borderWidth: '1',\n display: 'flex',\n height: '48',\n overflow: 'hidden',\n '&:has(button:is(:disabled, [aria-disabled=true]))': {\n borderColor: 'border/disabled',\n },\n },\n fieldTrigger: {\n ...chipButton,\n flex: '1',\n gap: '8',\n minWidth: 0,\n paddingInline: '16',\n textAlign: 'start',\n textStyle: 'body/lg/regular',\n },\n fieldIcon: {\n color: 'icon/secondary',\n flexShrink: 0,\n },\n fieldValue: {\n color: 'text/body',\n flex: '1',\n minWidth: 0,\n truncate: true,\n },\n fieldChevron: {\n color: 'icon/primary',\n flexShrink: 0,\n },\n fieldRemove: {\n ...chipButton,\n color: 'icon/primary',\n flexShrink: 0,\n justifyContent: 'center',\n width: '48',\n },\n },\n variants: {\n // Under a page header: a bottom border and the page's inline padding. `capped` is the centred\n // column, `full` the full-width one, which starts at 24 like the default `BitkitPageHeader`.\n pageLayout: {\n capped: {\n root: {\n borderBlockEndWidth: '1',\n borderColor: 'border/regular',\n paddingInline: { base: '16', tablet: '32' },\n },\n },\n full: {\n root: {\n borderBlockEndWidth: '1',\n borderColor: 'border/regular',\n paddingInlineEnd: { base: '16', tablet: '32' },\n paddingInlineStart: { base: '16', tablet: '24' },\n },\n },\n },\n contentAlign: {\n center: {},\n start: {\n root: {\n justifyContent: 'flex-start',\n },\n },\n },\n },\n});\n\nexport default filterSlotRecipe;\n"],"mappings":";;;AAIA,IAAM,aAAgC;CACpC,YAAY;CACZ,WAAW;CACX,SAAS;CACT,QAAQ;EACN,YAAY;EACZ,SAAS,EACP,YAAY,oBACd;CACF;CACA,SAAS,EACP,YAAY,oBACd;CACA,WAAW;EACT,QAAQ;EACR,oBAAoB,EAClB,OAAO,gBACT;EACA,QAAQ,EACN,YAAY,cACd;CACF;AACF;AAIA,IAAM,mBAAsC;CAC1C,cAAc;CACd,eAAe;CACf,cAAc;CACd,cAAc;AAChB;AAEA,IAAM,qBAAwC;CAC5C,OAAO;CACP,QAAQ;CACR,SAAS,EACP,OAAO,gBACT;CACA,QAAQ;EACN,YAAY;EACZ,OAAO;EACP,SAAS,EACP,YAAY,cACd;CACF;CACA,SAAS,EACP,YAAY,cACd;CACA,UAAU;EACR,QAAQ;GACN,YAAY;GACZ,SAAS,EACP,YAAY,qBACd;EACF;EACA,SAAS,EACP,YAAY,qBACd;CACF;AACF;AAEA,IAAM,mBAAmB,iBAAiB;CACxC,WAAW;CACX,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,MAAM;EACJ,MAAM;GACJ,YAAY;GACZ,SAAS;GACT,gBAAgB;GAChB,cAAc;GACd,eAAe;EACjB;EACA,SAAS;GACP,YAAY;GACZ,SAAS;GACT,MAAM;GACN,KAAK;GACL,UAAU;EACZ;EACA,SAAS;GACP,YAAY;GACZ,SAAS;GACT,MAAM;GACN,KAAK;GACL,UAAU;GACV,cAAc;EAChB;EACA,MAAM;GACJ,OAAO;GAEP,SAAS;GACT,YAAY;GACZ,SAAS;EACX;EACA,OAAO;GACL,YAAY;GACZ,SAAS;GACT,MAAM;GACN,UAAU;GACV,KAAK;GACL,UAAU;EACZ;EACA,aAAa;GACX,WAAW;GACX,aAAa;GACb,wBAAwB;GACxB,SAAS;GACT,YAAY;GACZ,oBAAoB;EACtB;EACA,QAAQ;GACN,YAAY;GACZ,YAAY;GACZ,cAAc;GACd,QAAQ;GACR,OAAO;GACP,SAAS;GACT,KAAK;GACL,QAAQ;GACR,eAAe;GACf,OAAO,IAAI,GAAG;GACd,QAAQ,EACN,YAAY,uBACd;GACA,8BAA8B;EAChC;EACA,aAAa;GACX,YAAY;GACZ,OAAO;GACP,MAAM;GACN,UAAU;GACV,SAAS;GACT,WAAW;GACX,cAAc,EACZ,OAAO,yBACT;GAEA,mCAAmC,EACjC,YAAY,OACd;EACF;EACA,QAAQ;GACN,YAAY;GACZ,cAAc;GACd,SAAS;GACT,YAAY;GACZ,UAAU;EACZ;EACA,YAAY;GACV,YAAY;GACZ,cAAc;GACd,OAAO;GACP,QAAQ;GACR,SAAS;GACT,KAAK;GACL,QAAQ;GACR,eAAe;GACf,UAAU;GACV,WAAW;GACX,YAAY;GAEZ,+BAA+B,EAC7B,OAAO,gBACT;GAEA,QAAQ;IACN,YAAY;IACZ,SAAS;IACT,QAAQ;IACR,gBAAgB;IAChB,UAAU;IACV,KAAK;IACL,OAAO;GACT;GACA,kGAAkG,EAChG,QAAQ,EACN,SAAS,OACX,EACF;GACA,8BAA8B;GAC9B,QAAQ;IACN,YAAY;IACZ,OAAO;IACP,+BAA+B,EAC7B,OAAO,iBACT;IACA,SAAS,EACP,YAAY,oBACd;GACF;GACA,SAAS;IACP,YAAY;IACZ,OAAO;GACT;GACA,UAAU;IACR,YAAY;IAEZ,WAAW;IACX,OAAO;IACP,+BAA+B,EAC7B,OAAO,iBACT;IACA,QAAQ,EACN,YAAY,qBACd;GACF;GAEA,WAAW;GACX,WAAW;EACb;EACA,gBAAgB,EACd,eAAe,IACjB;EACA,MAAM;GACJ,YAAY;GACZ,YAAY;GACZ,aAAa;GACb,cAAc;GACd,aAAa;GACb,SAAS;GACT,QAAQ;GACR,UAAU,IAAI,GAAG;GACjB,UAAU;GACV,UAAU;GACV,WAAW;GACX,qDAAqD,EACnD,aAAa,kBACf;GAEA,+BAA+B;IAC7B,WAAW;IAEX,4BAA4B,EAC1B,YAAY,qBACd;GACF;GAEA,wEAAwE;IACtE,WAAW;IACX,MAAM;IACN,UAAU;GACZ;EACF;EACA,aAAa;GACX,GAAG;GACH,MAAM;GACN,KAAK;GACL,UAAU;GACV,kBAAkB;GAClB,oBAAoB;GACpB,YAAY;GACZ,2BAA2B,EACzB,oBAAoB,IACtB;GACA,0CAA0C,EACxC,OAAO,iBACT;EACF;EACA,WAAW;GACT,OAAO;GACP,YAAY;EACd;EACA,WAAW;GACT,OAAO;GACP,UAAU;GACV,UAAU;EACZ;EACA,UAAU;GACR,OAAO;GACP,YAAY;GACZ,iBAAiB;EACnB;EACA,aAAa;GACX,OAAO;GACP,YAAY;GACZ,mBAAmB;EACrB;EACA,YAAY;GACV,GAAG;GACH,OAAO;GACP,YAAY;GACZ,kBAAkB;GAClB,oBAAoB;EACtB;EACA,gBAAgB;GAEd,WAAW;GAEX,UAAU,IAAI,GAAG;GACjB,UAAU;GACV,OAAO;GAEP,gCAAgC,EAC9B,OAAO,IAAI,GAAG,EAChB;GAEA,+BAA+B,EAC7B,UAAU,0CACZ;GAEA,6CAA6C,EAC3C,iBAAiB,EACnB;EACF;EACA,SAAS;GACP,YAAY;GACZ,cAAc;GACd,WAAW;GACX,SAAS;GACT,eAAe;GACf,WAAW;GACX,SAAS;GACT,WAAW;GACX,cAAc;GACd,OAAO,IAAI,GAAG;GACd,QAAQ;EACV;EACA,aAAa;GACX,YAAY;GACZ,OAAO;GACP,QAAQ;GACR,SAAS;GACT,KAAK;GACL,WAAW;GACX,cAAc;GACd,eAAe;GACf,WAAW;GACX,YAAY;GACZ,cAAc;IACZ,YAAY;IACZ,SAAS,EACP,YAAY,oBACd;GACF;GACA,SAAS,EACP,YAAY,oBACd;GACA,WAAW;IACT,OAAO;IACP,QAAQ;IACR,cAAc,EACZ,YAAY,cACd;IAEA,0BAA0B;KACxB,OAAO;KACP,cAAc,EACZ,YAAY,mBACd;IACF;GACF;GAEA,gDAAgD,EAC9C,YAAY,SACd;EACF;EACA,cAAc;GACZ,OAAO;GACP,cAAc;GACd,eAAe;GACf,WAAW;EACb;EACA,aAAa;GACX,OAAO;GACP,YAAY;GACZ,mBAAmB;EACrB;EACA,kBAAkB;GAChB,YAAY;GACZ,OAAO;GACP,UAAU;GACV,QAAQ;EACV;EACA,oBAAoB;GAClB,YAAY;GACZ,SAAS;GACT,OAAO;GACP,gBAAgB;GAChB,SAAS;GACT,UAAU;GACV,QAAQ;EACV;EACA,UAAU;GACR,YAAY;GACZ,cAAc;GACd,WAAW;GACX,SAAS;GACT,MAAM;GACN,eAAe;GACf,WAAW;GACX,SAAS;GACT,WAAW;GACX,cAAc;EAChB;EACA,cAAc;GACZ,GAAG;GACH,WAAW;GACX,OAAO;GACP,KAAK;GACL,WAAW;GACX,cAAc;GACd,eAAe;GACf,WAAW;GACX,WAAW;GACX,WAAW;IACT,OAAO;IACP,QAAQ;IACR,QAAQ,EACN,YAAY,cACd;IACA,0BAA0B;KACxB,OAAO;KACP,oBAAoB,EAClB,OAAO,gBACT;IACF;GACF;EACF;EACA,oBAAoB;GAClB,OAAO;GACP,WAAW;EACb;EACA,gBAAgB;GACd,YAAY;GACZ,SAAS;GACT,KAAK;GACL,kBAAkB;EACpB;EACA,eAAe;GACb,YAAY;GACZ,iBAAiB;GACjB,mBAAmB;GACnB,eAAe;EACjB;EAGA,aAAa;GACX,SAAS;GACT,eAAe;GACf,WAAW;GACX,2EAA2E,EACzE,WAAW,EACb;GACA,0CAA0C;IACxC,SAAS;IACT,eAAe;GACjB;EACF;EACA,eAAe;GACb,YAAY;GACZ,SAAS;GACT,KAAK;GACL,iBAAiB;GACjB,mBAAmB;GACnB,kBAAkB;GAClB,oBAAoB;EACtB;EACA,oBAAoB,EAClB,MAAM,IACR;EACA,cAAc;GACZ,WAAW,IAAI,GAAG;GAClB,WAAW;GACX,mBAAmB;GACnB,eAAe;GAEf,wBAAwB,EACtB,OAAO,iBACT;GACA,oEAAoE,EAClE,OAAO,eACT;GACA,kFAAkF,EAChF,OAAO,mBACT;EACF;EACA,gBAAgB;GACd,OAAO;GACP,WAAW;EACb;EACA,SAAS;GACP,cAAc;GACd,eAAe;EACjB;EACA,SAAS;GACP,SAAS;GACT,eAAe;GACf,KAAK;GACL,mBAAmB;GACnB,eAAe;EACjB;EACA,gBAAgB;GACd,SAAS;GACT,eAAe;GACf,KAAK;GACL,WAAW,IAAI,GAAG;GAClB,WAAW;GACX,WAAW;EACb;EACA,qBAAqB;GACnB,OAAO;GACP,WAAW;EACb;EACA,WAAW;GACT,YAAY;GACZ,qBAAqB;GACrB,aAAa;GACb,SAAS;GACT,KAAK;GACL,gBAAgB;GAChB,SAAS;EACX;EACA,eAAe;GACb,GAAG;GACH,WAAW;GACX,YAAY;GACZ,aAAa;GACb,cAAc;GACd,aAAa;GACb,OAAO;GACP,KAAK;GACL,QAAQ;GACR,eAAe;GACf,WAAW;GACX,OAAO,EACL,OAAO,eACT;GACA,WAAW;IACT,aAAa;IACb,OAAO;IACP,OAAO,EACL,OAAO,gBACT;GACF;EACF;EACA,cAAc;GACZ,YAAY;GACZ,qBAAqB;GACrB,aAAa;GACb,QAAQ;GACR,OAAO;GACP,SAAS;GACT,KAAK;GACL,QAAQ,IAAI,EAAE;GACd,eAAe;GAEf,8BAA8B;IAC5B,GAAG;IACH,eAAe;GACjB;EACF;EACA,mBAAmB;GACjB,YAAY;GACZ,OAAO;GACP,MAAM;GACN,UAAU;GACV,SAAS;GACT,WAAW;GACX,cAAc,EACZ,OAAO,yBACT;GACA,mCAAmC,EACjC,YAAY,OACd;EACF;EACA,cAAc;GACZ,YAAY;GACZ,qBAAqB;GACrB,aAAa;GACb,SAAS;GACT,YAAY;GACZ,KAAK;GAEL,cAAc;GACd,eAAe;IAAE,MAAM;IAAM,QAAQ;GAAK;EAC5C;EACA,aAAa;GACX,OAAO;GACP,MAAM;GACN,WAAW;EACb;EACA,mBAAmB;GACjB,YAAY;GACZ,qBAAqB;GACrB,aAAa;GACb,SAAS;GACT,YAAY;GACZ,KAAK;GACL,cAAc;GAEd,eAAe;IAAE,MAAM;IAAM,QAAQ;GAAK;EAC5C;EACA,qBAAqB;GACnB,OAAO;GACP,WAAW;EACb;EACA,kBAAkB;GAChB,OAAO;GACP,WAAW;EACb;EAEA,YAAY;GACV,SAAS;GACT,eAAe;GACf,KAAK;EACP;EACA,cAAc;GACZ,SAAS;GACT,KAAK;GACL,SAAS,EACP,MAAM,IACR;EACF;EAEA,iBAAiB;GACf,OAAO;GACP,SAAS;GACT,YAAY;GACZ,2BAA2B,EACzB,YAAY,SACd;EACF;EACA,oBAAoB,EAClB,YAAY,EACd;EACA,OAAO;GACL,SAAS;GACT,eAAe;GACf,KAAK;EACP;EACA,YAAY;GACV,OAAO;GACP,WAAW;EACb;EACA,cAAc;GACZ,YAAY;GACZ,aAAa;GACb,cAAc;GACd,aAAa;GACb,SAAS;GACT,QAAQ;GACR,UAAU;GACV,qDAAqD,EACnD,aAAa,kBACf;EACF;EACA,cAAc;GACZ,GAAG;GACH,MAAM;GACN,KAAK;GACL,UAAU;GACV,eAAe;GACf,WAAW;GACX,WAAW;EACb;EACA,WAAW;GACT,OAAO;GACP,YAAY;EACd;EACA,YAAY;GACV,OAAO;GACP,MAAM;GACN,UAAU;GACV,UAAU;EACZ;EACA,cAAc;GACZ,OAAO;GACP,YAAY;EACd;EACA,aAAa;GACX,GAAG;GACH,OAAO;GACP,YAAY;GACZ,gBAAgB;GAChB,OAAO;EACT;CACF;CACA,UAAU;EAGR,YAAY;GACV,QAAQ,EACN,MAAM;IACJ,qBAAqB;IACrB,aAAa;IACb,eAAe;KAAE,MAAM;KAAM,QAAQ;IAAK;GAC5C,EACF;GACA,MAAM,EACJ,MAAM;IACJ,qBAAqB;IACrB,aAAa;IACb,kBAAkB;KAAE,MAAM;KAAM,QAAQ;IAAK;IAC7C,oBAAoB;KAAE,MAAM;KAAM,QAAQ;IAAK;GACjD,EACF;EACF;EACA,cAAc;GACZ,QAAQ,CAAC;GACT,OAAO,EACL,MAAM,EACJ,gBAAgB,aAClB,EACF;EACF;CACF;AACF,CAAC"}
1
+ {"version":3,"file":"Filter.recipe.js","names":[],"sources":["../../../lib/theme/slot-recipes/Filter.recipe.ts"],"sourcesContent":["import { defineSlotRecipe, type SystemStyleObject } from '@chakra-ui/react/styled-system';\n\nimport { rem } from '../themeUtils';\n\nconst chipButton: SystemStyleObject = {\n alignItems: 'center',\n alignSelf: 'stretch',\n display: 'flex',\n _hover: {\n background: 'background/hover',\n _active: {\n background: 'background/active',\n },\n },\n _active: {\n background: 'background/active',\n },\n _disabled: {\n cursor: 'not-allowed',\n '& :is(span, svg)': {\n color: 'text/disabled',\n },\n _hover: {\n background: 'transparent',\n },\n },\n};\n\n// The keyboard focus ring for a wrapper whose input has no outline of its own. Chakra's `focusRing`\n// only fires on the focused element itself, so the global ring variables are applied directly.\nconst wrapperFocusRing: SystemStyleObject = {\n outlineColor: 'var(--focus-ring-color)',\n outlineOffset: 'var(--focus-ring-offset)',\n outlineStyle: 'var(--focus-ring-style)',\n outlineWidth: 'var(--focus-ring-width)',\n};\n\nconst switchItemDisabled: SystemStyleObject = {\n color: 'text/disabled',\n cursor: 'not-allowed',\n '& svg': {\n color: 'icon/disabled',\n },\n _hover: {\n background: 'transparent',\n color: 'text/disabled',\n _active: {\n background: 'transparent',\n },\n },\n _active: {\n background: 'transparent',\n },\n _checked: {\n _hover: {\n background: 'background/primary',\n _active: {\n background: 'background/primary',\n },\n },\n _active: {\n background: 'background/primary',\n },\n },\n};\n\nconst filterSlotRecipe = defineSlotRecipe({\n className: 'filter',\n slots: [\n 'root',\n 'content',\n 'filters',\n 'icon',\n 'items',\n 'searchBlock',\n 'search',\n 'searchInput',\n 'switch',\n 'switchItem',\n 'switchItemText',\n 'chip',\n 'chipTrigger',\n 'chipLabel',\n 'chipValue',\n 'chipIcon',\n 'chipChevron',\n 'chipRemove',\n 'popoverContent',\n 'addMenu',\n 'addMenuItem',\n 'addMenuLabel',\n 'addMenuIcon',\n 'addSheetBackdrop',\n 'addSheetPositioner',\n 'addSheet',\n 'addSheetItem',\n 'addSheetItemReason',\n 'calendarFooter',\n 'popoverSearch',\n 'popoverBody',\n 'popoverFooter',\n 'popoverFooterStart',\n 'checkboxList',\n 'listHelperText',\n 'loading',\n 'pattern',\n 'patternResults',\n 'patternResultsLabel',\n 'mobileBar',\n 'mobileTrigger',\n 'mobileSearch',\n 'mobileSearchInput',\n 'mobileHeader',\n 'mobileTitle',\n 'mobilePanelHeader',\n 'mobilePanelOverline',\n 'mobilePanelTitle',\n 'mobileBody',\n 'mobileFooter',\n 'mobileListCheck',\n 'mobileListCheckbox',\n 'field',\n 'fieldLabel',\n 'fieldControl',\n 'fieldTrigger',\n 'fieldIcon',\n 'fieldValue',\n 'fieldChevron',\n 'fieldRemove',\n ],\n base: {\n // No padding of its own: placed like any block, its edges line up with what's around it.\n root: {\n background: 'background/primary',\n display: 'flex',\n justifyContent: 'center',\n },\n content: {\n alignItems: 'flex-start',\n display: 'flex',\n flex: '1',\n gap: '16',\n minWidth: 0,\n },\n filters: {\n alignItems: 'flex-start',\n display: 'flex',\n flex: '1',\n gap: '12',\n minWidth: 0,\n paddingBlock: '4',\n },\n icon: {\n color: 'icon/tertiary',\n // Flex, so the inline svg's line box adds no extra height.\n display: 'flex',\n flexShrink: 0,\n padding: '4',\n },\n items: {\n alignItems: 'center',\n display: 'flex',\n flex: '1',\n flexWrap: 'wrap',\n gap: '12',\n minWidth: 0,\n },\n searchBlock: {\n alignSelf: 'stretch',\n borderColor: 'border/minimal',\n borderInlineStartWidth: '1',\n display: 'flex',\n flexShrink: 0,\n paddingInlineStart: '16',\n },\n search: {\n alignItems: 'center',\n background: 'background/primary',\n borderRadius: '4',\n cursor: 'text',\n color: 'icon/tertiary',\n display: 'flex',\n gap: '8',\n height: '40',\n paddingInline: '8',\n width: rem(148),\n _hover: {\n background: 'background/secondary',\n },\n '&:has(input:focus-visible)': wrapperFocusRing,\n },\n searchInput: {\n background: 'transparent',\n color: 'input/text/inputValue',\n flex: '1',\n minWidth: 0,\n outline: 'none',\n textStyle: 'body/md/regular',\n _placeholder: {\n color: 'input/text/placeholder',\n },\n // The clear button replaces the native cancel glyph of `type=\"search\"`.\n '&::-webkit-search-cancel-button': {\n appearance: 'none',\n },\n },\n switch: {\n background: 'background/secondary',\n borderRadius: '4',\n display: 'inline-flex',\n flexShrink: 0,\n position: 'relative',\n },\n switchItem: {\n alignItems: 'center',\n borderRadius: '4',\n color: 'text/secondary',\n cursor: 'pointer',\n display: 'flex',\n gap: '4',\n height: '32',\n paddingInline: '8',\n position: 'relative',\n textStyle: 'body/md/regular',\n whiteSpace: 'nowrap',\n // An item's own `iconColor` is left alone, except when disabled.\n '& svg:not([data-own-color])': {\n color: 'icon/tertiary',\n },\n // Divider after an unselected item, hidden next to the selected or hovered one.\n _after: {\n background: 'border/regular',\n content: '\"\"',\n height: '16',\n insetInlineEnd: 0,\n position: 'absolute',\n top: '8',\n width: '1',\n },\n '&:last-of-type, &[data-state=checked], &:hover, &:has(+ [data-state=checked]), &:has(+ :hover)': {\n _after: {\n display: 'none',\n },\n },\n '&:has(input:focus-visible)': wrapperFocusRing,\n _hover: {\n background: 'background/hover',\n color: 'text/primary',\n '& svg:not([data-own-color])': {\n color: 'icon/secondary',\n },\n _active: {\n background: 'background/active',\n },\n },\n _active: {\n background: 'background/active',\n color: 'text/primary',\n },\n _checked: {\n background: 'background/primary',\n // Inset, so the selected item is no taller than the others.\n boxShadow: 'inset 0 0 0 1px var(--colors-border\\\\/strong)',\n color: 'text/primary',\n '& svg:not([data-own-color])': {\n color: 'icon/secondary',\n },\n _hover: {\n background: 'background/primary',\n },\n },\n // Read-only while the page loads, so the item keeps a focus handed to it; it looks disabled.\n _disabled: switchItemDisabled,\n _readOnly: switchItemDisabled,\n },\n switchItemText: {\n paddingInline: '4',\n },\n chip: {\n alignItems: 'center',\n background: 'background/primary',\n borderColor: 'border/strong',\n borderRadius: '4',\n borderWidth: '1',\n display: 'inline-flex',\n height: '32',\n maxWidth: rem(320),\n minWidth: 0,\n overflow: 'hidden',\n textStyle: 'body/md/regular',\n '&:has(button:is(:disabled, [aria-disabled=true]))': {\n borderColor: 'border/disabled',\n },\n // The chip's popover is open: Zag marks the trigger inside it as expanded.\n '&:has([aria-expanded=true])': {\n boxShadow: '0 0 0 0.125rem var(--focus-ring-color)',\n // Figma's selected chip stays white, even under the pointer that just opened it.\n '& button, & button:hover': {\n background: 'background/primary',\n },\n },\n // The date chip's trigger sits inside the calendar's root and control divs; they stretch like a direct child would.\n '& [data-scope=date-picker]:is([data-part=root], [data-part=control])': {\n alignSelf: 'stretch',\n flex: '1',\n minWidth: 0,\n },\n },\n chipTrigger: {\n ...chipButton,\n flex: '1',\n gap: '4',\n minWidth: 0,\n paddingInlineEnd: '8',\n paddingInlineStart: '12',\n whiteSpace: 'nowrap',\n '&:has([data-chip-icon])': {\n paddingInlineStart: '8',\n },\n '&:is(:hover, :active) [data-chip-icon]': {\n color: 'icon/secondary',\n },\n },\n chipLabel: {\n color: 'text/secondary',\n flexShrink: 0,\n },\n chipValue: {\n color: 'text/body',\n minWidth: 0,\n truncate: true,\n },\n chipIcon: {\n color: 'icon/tertiary',\n flexShrink: 0,\n marginInlineEnd: '4',\n },\n chipChevron: {\n color: 'icon/primary',\n flexShrink: 0,\n marginInlineStart: '8',\n },\n chipRemove: {\n ...chipButton,\n color: 'icon/primary',\n flexShrink: 0,\n paddingInlineEnd: '8',\n paddingInlineStart: '4',\n },\n popoverContent: {\n // The popover's 60vh cap, or less where the space next to the bar is shorter.\n maxHeight: 'min(60vh, var(--available-height, 60vh))',\n // As wide as its content: at least its chip and 320px, at most 800px.\n maxWidth: rem(800),\n minWidth: 'max(var(--reference-width, 0px), 20rem)',\n width: 'max-content',\n // The wildcard pattern's explanation would otherwise stretch it to its widest.\n '&:has([data-filter-pattern])': {\n width: rem(480),\n },\n // The footer's top padding is the gap under the list, so the list adds none of its own.\n '& [data-scope=listbox][data-part=content]': {\n paddingBlockEnd: 0,\n },\n },\n addMenu: {\n background: 'background/primary',\n borderRadius: '8',\n boxShadow: 'elevation/lg',\n display: 'flex',\n flexDirection: 'column',\n maxHeight: 'var(--available-height)',\n outline: 'none',\n overflowY: 'auto',\n paddingBlock: '8',\n width: rem(240),\n zIndex: 'popover',\n },\n addMenuItem: {\n alignItems: 'center',\n color: 'text/body',\n cursor: 'pointer',\n display: 'flex',\n gap: '4',\n minHeight: '40',\n paddingBlock: '8',\n paddingInline: '16',\n textStyle: 'body/md/regular',\n userSelect: 'none',\n _highlighted: {\n background: 'background/hover',\n _active: {\n background: 'background/active',\n },\n },\n _active: {\n background: 'background/active',\n },\n _disabled: {\n color: 'text/disabled',\n cursor: 'not-allowed',\n _highlighted: {\n background: 'transparent',\n },\n // Not applicable yet: `aria-disabled` but reachable, so the keyboard highlight still shows.\n '&[data-not-applicable]': {\n color: 'text/tertiary',\n _highlighted: {\n background: 'background/hover',\n },\n },\n },\n // The chevron only shows on the row under the pointer or keyboard.\n '&:not([data-highlighted]) [data-add-chevron]': {\n visibility: 'hidden',\n },\n },\n addMenuLabel: {\n color: 'text/tertiary',\n paddingBlock: '8',\n paddingInline: '16',\n textStyle: 'heading/h6',\n },\n addMenuIcon: {\n color: 'icon/tertiary',\n flexShrink: 0,\n marginInlineStart: 'auto',\n },\n addSheetBackdrop: {\n background: 'utilities/overlay-light',\n inset: 0,\n position: 'fixed',\n zIndex: 'calc({zIndex.dialogOverlay} + var(--layer-index, 0))',\n },\n addSheetPositioner: {\n alignItems: 'flex-end',\n display: 'flex',\n inset: 0,\n justifyContent: 'stretch',\n padding: '16',\n position: 'fixed',\n zIndex: 'calc({zIndex.dialog} + var(--layer-index, 0))',\n },\n addSheet: {\n background: 'background/primary',\n borderRadius: '8',\n boxShadow: 'elevation/lg',\n display: 'flex',\n flex: '1',\n flexDirection: 'column',\n maxHeight: '80dvh',\n outline: 'none',\n overflowY: 'auto',\n paddingBlock: '8',\n },\n addSheetItem: {\n ...chipButton,\n alignSelf: 'auto',\n color: 'text/body',\n gap: '12',\n minHeight: '48',\n paddingBlock: '8',\n paddingInline: '16',\n textAlign: 'start',\n textStyle: 'body/lg/regular',\n _disabled: {\n color: 'text/disabled',\n cursor: 'not-allowed',\n _hover: {\n background: 'transparent',\n },\n '&[data-not-applicable]': {\n color: 'text/tertiary',\n '& :is(span, svg)': {\n color: 'text/tertiary',\n },\n },\n },\n },\n addSheetItemReason: {\n color: 'text/tertiary',\n textStyle: 'body/sm/regular',\n },\n calendarFooter: {\n alignItems: 'center',\n display: 'flex',\n gap: '8',\n marginBlockStart: '24',\n },\n popoverSearch: {\n flexShrink: 0,\n paddingBlockEnd: '8',\n paddingBlockStart: '8',\n paddingInline: '12',\n },\n // When the popover is capped by the space available, the list (or pattern results) gives way and\n // scrolls on its own, rather than running under the footer: every part may shrink below its content.\n popoverBody: {\n display: 'flex',\n flexDirection: 'column',\n minHeight: 0,\n '& > *, & [data-scope=listbox]:is([data-part=root], [data-part=content])': {\n minHeight: 0,\n },\n '& [data-scope=listbox][data-part=root]': {\n display: 'flex',\n flexDirection: 'column',\n },\n },\n popoverFooter: {\n alignItems: 'center',\n display: 'flex',\n gap: '8',\n paddingBlockEnd: '16',\n paddingBlockStart: '24',\n paddingInline: '16',\n },\n popoverFooterStart: {\n flex: '1',\n },\n checkboxList: {\n maxHeight: rem(200),\n overflowY: 'auto',\n paddingBlockStart: '8',\n paddingInline: '20',\n // An option's icon: secondary, primary while hovered, interactive once checked.\n '& [data-option-icon]': {\n color: 'icon/secondary',\n },\n '& [data-scope=checkbox][data-part=root]:hover [data-option-icon]': {\n color: 'icon/primary',\n },\n '& [data-scope=checkbox][data-part=root][data-state=checked] [data-option-icon]': {\n color: 'icon/interactive',\n },\n },\n listHelperText: {\n color: 'text/secondary',\n textStyle: 'body/sm/regular',\n },\n loading: {\n paddingBlock: '8',\n paddingInline: '16',\n },\n pattern: {\n display: 'flex',\n flexDirection: 'column',\n gap: '24',\n paddingBlockStart: '8',\n paddingInline: '16',\n },\n patternResults: {\n display: 'flex',\n flexDirection: 'column',\n gap: '8',\n maxHeight: rem(176),\n minHeight: 0,\n overflowY: 'auto',\n },\n patternResultsLabel: {\n color: 'text/primary',\n textStyle: 'comp/input/label',\n },\n mobileBar: {\n alignItems: 'center',\n borderBlockEndWidth: '1',\n borderColor: 'border/minimal',\n display: 'flex',\n gap: '12',\n justifyContent: 'space-between',\n padding: '16',\n },\n mobileTrigger: {\n ...chipButton,\n alignSelf: 'auto',\n background: 'background/primary',\n borderColor: 'border/strong',\n borderRadius: '4',\n borderWidth: '1',\n color: 'text/primary',\n gap: '8',\n height: '32',\n paddingInline: '8',\n textStyle: 'comp/button/sm',\n _icon: {\n color: 'icon/primary',\n },\n _disabled: {\n borderColor: 'border/disabled',\n color: 'text/disabled',\n _icon: {\n color: 'icon/disabled',\n },\n },\n },\n mobileSearch: {\n alignItems: 'center',\n borderBlockEndWidth: '1',\n borderColor: 'border/minimal',\n cursor: 'text',\n color: 'icon/tertiary',\n display: 'flex',\n gap: '12',\n height: rem(56),\n paddingInline: '16',\n // Drawn inside, since the row runs edge to edge.\n '&:has(input:focus-visible)': {\n ...wrapperFocusRing,\n outlineOffset: 'calc(var(--focus-ring-width) * -1)',\n },\n },\n mobileSearchInput: {\n background: 'transparent',\n color: 'input/text/inputValue',\n flex: '1',\n minWidth: 0,\n outline: 'none',\n textStyle: 'body/lg/regular',\n _placeholder: {\n color: 'input/text/placeholder',\n },\n '&::-webkit-search-cancel-button': {\n appearance: 'none',\n },\n },\n mobileHeader: {\n alignItems: 'center',\n borderBlockEndWidth: '1',\n borderColor: 'border/minimal',\n display: 'flex',\n flexShrink: 0,\n gap: '12',\n // Matches the docked drawer's body and footer inset.\n paddingBlock: '16',\n paddingInline: { base: '16', tablet: '24' },\n },\n mobileTitle: {\n color: 'text/primary',\n flex: '1',\n textStyle: 'heading/mobile/h2',\n },\n mobilePanelHeader: {\n alignItems: 'center',\n borderBlockEndWidth: '1',\n borderColor: 'border/minimal',\n display: 'flex',\n flexShrink: 0,\n gap: '12',\n paddingBlock: '12',\n // Matches the docked drawer's footer inset.\n paddingInline: { base: '16', tablet: '24' },\n },\n mobilePanelOverline: {\n color: 'text/tertiary',\n textStyle: 'heading/h6',\n },\n mobilePanelTitle: {\n color: 'text/primary',\n textStyle: 'heading/mobile/h3',\n },\n // The docked drawer pads the body and footer itself.\n mobileBody: {\n display: 'flex',\n flexDirection: 'column',\n gap: '16',\n },\n mobileFooter: {\n display: 'flex',\n gap: '12',\n '& > *': {\n flex: '1',\n },\n },\n // Drawn in front of the label on mobile, with its column kept on unselected rows so the labels line up.\n mobileListCheck: {\n color: 'icon/interactive',\n display: 'flex',\n flexShrink: 0,\n '&[data-state=unchecked]': {\n visibility: 'hidden',\n },\n },\n mobileListCheckbox: {\n flexShrink: 0,\n },\n field: {\n display: 'flex',\n flexDirection: 'column',\n gap: '8',\n },\n fieldLabel: {\n color: 'text/primary',\n textStyle: 'comp/input/label',\n },\n fieldControl: {\n background: 'background/primary',\n borderColor: 'border/strong',\n borderRadius: '4',\n borderWidth: '1',\n display: 'flex',\n height: '48',\n overflow: 'hidden',\n '&:has(button:is(:disabled, [aria-disabled=true]))': {\n borderColor: 'border/disabled',\n },\n },\n fieldTrigger: {\n ...chipButton,\n flex: '1',\n gap: '8',\n minWidth: 0,\n paddingInline: '16',\n textAlign: 'start',\n textStyle: 'body/lg/regular',\n },\n fieldIcon: {\n color: 'icon/secondary',\n flexShrink: 0,\n },\n fieldValue: {\n color: 'text/body',\n flex: '1',\n minWidth: 0,\n truncate: true,\n },\n fieldChevron: {\n color: 'icon/primary',\n flexShrink: 0,\n },\n fieldRemove: {\n ...chipButton,\n color: 'icon/primary',\n flexShrink: 0,\n justifyContent: 'center',\n width: '48',\n },\n },\n variants: {\n // Under a page header: a bottom border and the page's inline padding. `capped` is the centred\n // column, `full` the full-width one, which starts at 24 like the default `BitkitPageHeader`.\n pageLayout: {\n capped: {\n root: {\n borderBlockEndWidth: '1',\n borderColor: 'border/regular',\n paddingBlock: '12',\n paddingInline: { base: '16', tablet: '32' },\n },\n },\n full: {\n root: {\n borderBlockEndWidth: '1',\n borderColor: 'border/regular',\n paddingBlock: '12',\n paddingInlineEnd: { base: '16', tablet: '32' },\n paddingInlineStart: { base: '16', tablet: '24' },\n },\n },\n },\n contentAlign: {\n center: {},\n start: {\n root: {\n justifyContent: 'flex-start',\n },\n },\n },\n },\n});\n\nexport default filterSlotRecipe;\n"],"mappings":";;;AAIA,IAAM,aAAgC;CACpC,YAAY;CACZ,WAAW;CACX,SAAS;CACT,QAAQ;EACN,YAAY;EACZ,SAAS,EACP,YAAY,oBACd;CACF;CACA,SAAS,EACP,YAAY,oBACd;CACA,WAAW;EACT,QAAQ;EACR,oBAAoB,EAClB,OAAO,gBACT;EACA,QAAQ,EACN,YAAY,cACd;CACF;AACF;AAIA,IAAM,mBAAsC;CAC1C,cAAc;CACd,eAAe;CACf,cAAc;CACd,cAAc;AAChB;AAEA,IAAM,qBAAwC;CAC5C,OAAO;CACP,QAAQ;CACR,SAAS,EACP,OAAO,gBACT;CACA,QAAQ;EACN,YAAY;EACZ,OAAO;EACP,SAAS,EACP,YAAY,cACd;CACF;CACA,SAAS,EACP,YAAY,cACd;CACA,UAAU;EACR,QAAQ;GACN,YAAY;GACZ,SAAS,EACP,YAAY,qBACd;EACF;EACA,SAAS,EACP,YAAY,qBACd;CACF;AACF;AAEA,IAAM,mBAAmB,iBAAiB;CACxC,WAAW;CACX,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,MAAM;EAEJ,MAAM;GACJ,YAAY;GACZ,SAAS;GACT,gBAAgB;EAClB;EACA,SAAS;GACP,YAAY;GACZ,SAAS;GACT,MAAM;GACN,KAAK;GACL,UAAU;EACZ;EACA,SAAS;GACP,YAAY;GACZ,SAAS;GACT,MAAM;GACN,KAAK;GACL,UAAU;GACV,cAAc;EAChB;EACA,MAAM;GACJ,OAAO;GAEP,SAAS;GACT,YAAY;GACZ,SAAS;EACX;EACA,OAAO;GACL,YAAY;GACZ,SAAS;GACT,MAAM;GACN,UAAU;GACV,KAAK;GACL,UAAU;EACZ;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GAChB,YAAY;GACZ,OAAO;GACP,UAAU;GACV,QAAQ;EACV;EACA,oBAAoB;GAClB,YAAY;GACZ,SAAS;GACT,OAAO;GACP,gBAAgB;GAChB,SAAS;GACT,UAAU;GACV,QAAQ;EACV;EACA,UAAU;GACR,YAAY;GACZ,cAAc;GACd,WAAW;GACX,SAAS;GACT,MAAM;GACN,eAAe;GACf,WAAW;GACX,SAAS;GACT,WAAW;GACX,cAAc;EAChB;EACA,cAAc;GACZ,GAAG;GACH,WAAW;GACX,OAAO;GACP,KAAK;GACL,WAAW;GACX,cAAc;GACd,eAAe;GACf,WAAW;GACX,WAAW;GACX,WAAW;IACT,OAAO;IACP,QAAQ;IACR,QAAQ,EACN,YAAY,cACd;IACA,0BAA0B;KACxB,OAAO;KACP,oBAAoB,EAClB,OAAO,gBACT;IACF;GACF;EACF;EACA,oBAAoB;GAClB,OAAO;GACP,WAAW;EACb;EACA,gBAAgB;GACd,YAAY;GACZ,SAAS;GACT,KAAK;GACL,kBAAkB;EACpB;EACA,eAAe;GACb,YAAY;GACZ,iBAAiB;GACjB,mBAAmB;GACnB,eAAe;EACjB;EAGA,aAAa;GACX,SAAS;GACT,eAAe;GACf,WAAW;GACX,2EAA2E,EACzE,WAAW,EACb;GACA,0CAA0C;IACxC,SAAS;IACT,eAAe;GACjB;EACF;EACA,eAAe;GACb,YAAY;GACZ,SAAS;GACT,KAAK;GACL,iBAAiB;GACjB,mBAAmB;GACnB,eAAe;EACjB;EACA,oBAAoB,EAClB,MAAM,IACR;EACA,cAAc;GACZ,WAAW,IAAI,GAAG;GAClB,WAAW;GACX,mBAAmB;GACnB,eAAe;GAEf,wBAAwB,EACtB,OAAO,iBACT;GACA,oEAAoE,EAClE,OAAO,eACT;GACA,kFAAkF,EAChF,OAAO,mBACT;EACF;EACA,gBAAgB;GACd,OAAO;GACP,WAAW;EACb;EACA,SAAS;GACP,cAAc;GACd,eAAe;EACjB;EACA,SAAS;GACP,SAAS;GACT,eAAe;GACf,KAAK;GACL,mBAAmB;GACnB,eAAe;EACjB;EACA,gBAAgB;GACd,SAAS;GACT,eAAe;GACf,KAAK;GACL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"}
@@ -1190,6 +1190,7 @@ declare const slotRecipes: {
1190
1190
  root: {
1191
1191
  borderBlockEndWidth: "1";
1192
1192
  borderColor: "border/regular";
1193
+ paddingBlock: "12";
1193
1194
  paddingInline: {
1194
1195
  base: "16";
1195
1196
  tablet: "32";
@@ -1200,6 +1201,7 @@ declare const slotRecipes: {
1200
1201
  root: {
1201
1202
  borderBlockEndWidth: "1";
1202
1203
  borderColor: "border/regular";
1204
+ paddingBlock: "12";
1203
1205
  paddingInlineEnd: {
1204
1206
  base: "16";
1205
1207
  tablet: "32";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bitrise/bitkit-v2",
3
3
  "private": false,
4
- "version": "0.3.481-beta.3087",
4
+ "version": "0.3.481-beta.3091",
5
5
  "description": "Bitrise Design System Components built with Chakra UI V3",
6
6
  "keywords": [
7
7
  "react",