@bitrise/bitkit-v2 0.3.475-beta.3009 → 0.3.475-beta.3012

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.
Files changed (124) hide show
  1. package/dist/components/BitkitCalendar/BitkitCalendar.d.ts +12 -0
  2. package/dist/components/BitkitCalendar/BitkitCalendar.js +7 -1
  3. package/dist/components/BitkitCalendar/BitkitCalendar.js.map +1 -1
  4. package/dist/components/BitkitCalendar/components/CalendarContent.d.ts +5 -1
  5. package/dist/components/BitkitCalendar/components/CalendarContent.js +60 -43
  6. package/dist/components/BitkitCalendar/components/CalendarContent.js.map +1 -1
  7. package/dist/components/BitkitCalendar/components/CalendarMonth.d.ts +4 -2
  8. package/dist/components/BitkitCalendar/components/CalendarMonth.js +15 -5
  9. package/dist/components/BitkitCalendar/components/CalendarMonth.js.map +1 -1
  10. package/dist/components/BitkitCalendar/components/CalendarMonthSelect.d.ts +2 -1
  11. package/dist/components/BitkitCalendar/components/CalendarMonthSelect.js +3 -2
  12. package/dist/components/BitkitCalendar/components/CalendarMonthSelect.js.map +1 -1
  13. package/dist/components/BitkitCalendar/components/CalendarNextTrigger.d.ts +3 -1
  14. package/dist/components/BitkitCalendar/components/CalendarNextTrigger.js +3 -3
  15. package/dist/components/BitkitCalendar/components/CalendarNextTrigger.js.map +1 -1
  16. package/dist/components/BitkitCalendar/components/CalendarPrevTrigger.d.ts +3 -1
  17. package/dist/components/BitkitCalendar/components/CalendarPrevTrigger.js +3 -3
  18. package/dist/components/BitkitCalendar/components/CalendarPrevTrigger.js.map +1 -1
  19. package/dist/components/BitkitCalendar/components/CalendarSelect.d.ts +1 -0
  20. package/dist/components/BitkitCalendar/components/CalendarSelect.js +4 -2
  21. package/dist/components/BitkitCalendar/components/CalendarSelect.js.map +1 -1
  22. package/dist/components/BitkitCalendar/components/CalendarYearSelect.d.ts +2 -1
  23. package/dist/components/BitkitCalendar/components/CalendarYearSelect.js +3 -2
  24. package/dist/components/BitkitCalendar/components/CalendarYearSelect.js.map +1 -1
  25. package/dist/components/BitkitDatePicker/BitkitDatePicker.d.ts +2 -0
  26. package/dist/components/BitkitDatePicker/BitkitDatePicker.js +2 -1
  27. package/dist/components/BitkitDatePicker/BitkitDatePicker.js.map +1 -1
  28. package/dist/components/BitkitFilter/BitkitFilter.context.d.ts +65 -0
  29. package/dist/components/BitkitFilter/BitkitFilter.context.js +82 -0
  30. package/dist/components/BitkitFilter/BitkitFilter.context.js.map +1 -0
  31. package/dist/components/BitkitFilter/BitkitFilter.d.ts +55 -0
  32. package/dist/components/BitkitFilter/BitkitFilter.js +240 -0
  33. package/dist/components/BitkitFilter/BitkitFilter.js.map +1 -0
  34. package/dist/components/BitkitFilter/BitkitFilter.utils.d.ts +18 -0
  35. package/dist/components/BitkitFilter/BitkitFilter.utils.js +42 -0
  36. package/dist/components/BitkitFilter/BitkitFilter.utils.js.map +1 -0
  37. package/dist/components/BitkitFilter/BitkitFilterAdd.d.ts +18 -0
  38. package/dist/components/BitkitFilter/BitkitFilterAdd.js +188 -0
  39. package/dist/components/BitkitFilter/BitkitFilterAdd.js.map +1 -0
  40. package/dist/components/BitkitFilter/BitkitFilterDateRange.d.ts +26 -0
  41. package/dist/components/BitkitFilter/BitkitFilterDateRange.js +118 -0
  42. package/dist/components/BitkitFilter/BitkitFilterDateRange.js.map +1 -0
  43. package/dist/components/BitkitFilter/BitkitFilterSearch.d.ts +23 -0
  44. package/dist/components/BitkitFilter/BitkitFilterSearch.js +70 -0
  45. package/dist/components/BitkitFilter/BitkitFilterSearch.js.map +1 -0
  46. package/dist/components/BitkitFilter/BitkitFilterSelect.d.ts +61 -0
  47. package/dist/components/BitkitFilter/BitkitFilterSelect.js +140 -0
  48. package/dist/components/BitkitFilter/BitkitFilterSelect.js.map +1 -0
  49. package/dist/components/BitkitFilter/BitkitFilterSwitch.d.ts +28 -0
  50. package/dist/components/BitkitFilter/BitkitFilterSwitch.js +87 -0
  51. package/dist/components/BitkitFilter/BitkitFilterSwitch.js.map +1 -0
  52. package/dist/components/BitkitFilter/components/FilterChip.d.ts +23 -0
  53. package/dist/components/BitkitFilter/components/FilterChip.js +64 -0
  54. package/dist/components/BitkitFilter/components/FilterChip.js.map +1 -0
  55. package/dist/components/BitkitFilter/components/FilterField.d.ts +15 -0
  56. package/dist/components/BitkitFilter/components/FilterField.js +58 -0
  57. package/dist/components/BitkitFilter/components/FilterField.js.map +1 -0
  58. package/dist/components/BitkitFilter/components/FilterPanel.d.ts +42 -0
  59. package/dist/components/BitkitFilter/components/FilterPanel.js +126 -0
  60. package/dist/components/BitkitFilter/components/FilterPanel.js.map +1 -0
  61. package/dist/components/BitkitFilter/components/FilterSearchInput.d.ts +15 -0
  62. package/dist/components/BitkitFilter/components/FilterSearchInput.js +41 -0
  63. package/dist/components/BitkitFilter/components/FilterSearchInput.js.map +1 -0
  64. package/dist/components/BitkitFilter/components/FilterSelectForm.d.ts +39 -0
  65. package/dist/components/BitkitFilter/components/FilterSelectForm.js +278 -0
  66. package/dist/components/BitkitFilter/components/FilterSelectForm.js.map +1 -0
  67. package/dist/components/BitkitMarkdown/BitkitMarkdown.js +1 -1
  68. package/dist/components/BitkitNoteCard/BitkitNoteCard.js +1 -1
  69. package/dist/components/index.d.ts +6 -1
  70. package/dist/main.js +8 -9
  71. package/dist/theme/recipes/index.d.ts +525 -0
  72. package/dist/theme/recipes/index.js +1 -3
  73. package/dist/theme/recipes/index.js.map +1 -1
  74. package/dist/theme/slot-recipes/DatePicker.recipe.d.ts +15 -0
  75. package/dist/theme/slot-recipes/DatePicker.recipe.js +72 -22
  76. package/dist/theme/slot-recipes/DatePicker.recipe.js.map +1 -1
  77. package/dist/theme/slot-recipes/DatePickerSelect.recipe.d.ts +82 -0
  78. package/dist/theme/slot-recipes/DatePickerSelect.recipe.js +28 -10
  79. package/dist/theme/slot-recipes/DatePickerSelect.recipe.js.map +1 -1
  80. package/dist/theme/slot-recipes/Filter.recipe.d.ts +37 -0
  81. package/dist/theme/slot-recipes/Filter.recipe.js +636 -0
  82. package/dist/theme/slot-recipes/Filter.recipe.js.map +1 -0
  83. package/dist/theme/slot-recipes/Listbox.recipe.d.ts +22 -0
  84. package/dist/theme/slot-recipes/Listbox.recipe.js +97 -0
  85. package/dist/theme/slot-recipes/Listbox.recipe.js.map +1 -0
  86. package/dist/theme/slot-recipes/Menu.recipe.js +6 -1
  87. package/dist/theme/slot-recipes/Menu.recipe.js.map +1 -1
  88. package/dist/theme/slot-recipes/Tag.recipe.d.ts +1 -1
  89. package/dist/theme/slot-recipes/index.d.ts +155 -2
  90. package/dist/theme/slot-recipes/index.js +4 -2
  91. package/dist/theme/slot-recipes/index.js.map +1 -1
  92. package/dist/utilities/BitkitPortalContext.js +3 -2
  93. package/dist/utilities/BitkitPortalContext.js.map +1 -1
  94. package/docs/v1-to-v2-migration-guide.md +48 -1
  95. package/package.json +1 -1
  96. package/dist/components/BitkitUIHeader/BitkitUIHeader.d.ts +0 -37
  97. package/dist/components/BitkitUIHeader/BitkitUIHeader.js +0 -100
  98. package/dist/components/BitkitUIHeader/BitkitUIHeader.js.map +0 -1
  99. package/dist/components/BitkitUIHeader/BitriseLogo.d.ts +0 -10
  100. package/dist/components/BitkitUIHeader/BitriseLogo.js +0 -86
  101. package/dist/components/BitkitUIHeader/BitriseLogo.js.map +0 -1
  102. package/dist/components/BitkitUIHeader/UIHeaderAccount.d.ts +0 -19
  103. package/dist/components/BitkitUIHeader/UIHeaderAccount.js +0 -38
  104. package/dist/components/BitkitUIHeader/UIHeaderAccount.js.map +0 -1
  105. package/dist/components/BitkitUIHeader/UIHeaderButton.d.ts +0 -33
  106. package/dist/components/BitkitUIHeader/UIHeaderButton.js +0 -41
  107. package/dist/components/BitkitUIHeader/UIHeaderButton.js.map +0 -1
  108. package/dist/components/BitkitUIHeader/UIHeaderContext.d.ts +0 -12
  109. package/dist/components/BitkitUIHeader/UIHeaderContext.js +0 -11
  110. package/dist/components/BitkitUIHeader/UIHeaderContext.js.map +0 -1
  111. package/dist/components/BitkitUIHeader/UIHeaderControl.d.ts +0 -64
  112. package/dist/components/BitkitUIHeader/UIHeaderControl.js +0 -66
  113. package/dist/components/BitkitUIHeader/UIHeaderControl.js.map +0 -1
  114. package/dist/components/BitkitUIHeader/UIHeaderNavButton.d.ts +0 -20
  115. package/dist/components/BitkitUIHeader/UIHeaderNavButton.js +0 -47
  116. package/dist/components/BitkitUIHeader/UIHeaderNavButton.js.map +0 -1
  117. package/dist/components/BitkitUIHeader/UIHeaderSearch.d.ts +0 -32
  118. package/dist/components/BitkitUIHeader/UIHeaderSearch.js +0 -96
  119. package/dist/components/BitkitUIHeader/UIHeaderSearch.js.map +0 -1
  120. package/dist/theme/recipes/UIHeaderButton.recipe.js +0 -111
  121. package/dist/theme/recipes/UIHeaderButton.recipe.js.map +0 -1
  122. package/dist/theme/slot-recipes/UIHeader.recipe.d.ts +0 -11
  123. package/dist/theme/slot-recipes/UIHeader.recipe.js +0 -237
  124. package/dist/theme/slot-recipes/UIHeader.recipe.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"UIHeaderNavButton.js","names":[],"sources":["../../../lib/components/BitkitUIHeader/UIHeaderNavButton.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { type HTMLChakraProps } from '@chakra-ui/react/styled-system';\nimport { forwardRef } from 'react';\n\nimport { IconMenuHamburger } from '../../icons';\nimport BitkitAvatar from '../BitkitAvatar/BitkitAvatar';\nimport { useUIHeaderContext } from './UIHeaderContext';\nimport { UIHeaderControlBase } from './UIHeaderControl';\n\nexport interface BitkitUIHeaderNavButtonProps extends Omit<HTMLChakraProps<'button'>, 'children'> {\n /** The accessible name. */\n label?: string;\n /** The current workspace. Shown as the avatar's initials when it has no logo. */\n name: string;\n /** The workspace's logo. Without one the avatar falls back to its initials. */\n src?: string;\n}\n\n/**\n * Opens `BitkitUISideNav` on mobile, where the navigation is a drawer rather than a rail. It sits\n * in the header's `leading` slot, which is hidden from the `tablet` breakpoint up.\n *\n * The two components do not know about each other: this button's `onClick` sets the navigation's\n * `open`, and the navigation asks to close through its own `onOpenChange`.\n *\n * It shows the current workspace, so switching workspaces is one tap away from anywhere.\n */\nconst UIHeaderNavButton = forwardRef<HTMLButtonElement, BitkitUIHeaderNavButtonProps>((props, ref) => {\n const { label = 'Open navigation', name, src, ...rest } = props;\n\n const { styles } = useUIHeaderContext();\n\n const avatarProps = src ? ({ src, variant: 'image' } as const) : ({ variant: 'letters' } as const);\n\n return (\n <UIHeaderControlBase ref={ref} footprint=\"navButton\" label={label} {...rest}>\n <BitkitAvatar name={name} size=\"32\" {...avatarProps} />\n <Box css={styles.navButtonBadge}>\n <IconMenuHamburger css={styles.navButtonIcon} size=\"16\" />\n </Box>\n </UIHeaderControlBase>\n );\n});\n\nUIHeaderNavButton.displayName = 'BitkitUIHeader.NavButton';\n\nexport default UIHeaderNavButton;\n"],"mappings":";;;;;;;;;;;;;;;;;AA2BA,IAAM,oBAAoB,YAA6D,OAAO,QAAQ;CACpG,MAAM,EAAE,QAAQ,mBAAmB,MAAM,KAAK,GAAG,SAAS;CAE1D,MAAM,EAAE,WAAW,mBAAmB;CAEtC,MAAM,cAAc,MAAO;EAAE;EAAK,SAAS;CAAQ,IAAe,EAAE,SAAS,UAAU;CAEvF,OACE,qBAAC,qBAAD;EAA0B;EAAK,WAAU;EAAmB;EAAO,GAAI;EAAvE,UAAA,CACE,oBAAC,cAAD;GAAoB;GAAM,MAAK;GAAK,GAAI;EAAc,CAAA,GACtD,oBAAC,KAAD;GAAK,KAAK,OAAO;GACf,UAAA,oBAAC,mBAAD;IAAmB,KAAK,OAAO;IAAe,MAAK;GAAM,CAAA;EACtD,CAAA,CACc;;AAEzB,CAAC;AAED,kBAAkB,cAAc"}
@@ -1,32 +0,0 @@
1
- import { BoxProps } from '@chakra-ui/react/box';
2
- import { Ref } from 'react';
3
- export interface BitkitUIHeaderSearchProps extends Omit<BoxProps, 'children' | 'onChange'> {
4
- /**
5
- * The search field, for anchoring the results to it. The component owns no results list: what a
6
- * search turns up differs per product, so the consumer renders its own panel against this.
7
- */
8
- inputRef?: Ref<HTMLInputElement>;
9
- /** The accessible name of both the button and the field. */
10
- label?: string;
11
- /**
12
- * Called when the button is pressed, and when Escape closes the field.
13
- *
14
- * From `tablet` up this opens the field in place. Below it there is no inline field — the button
15
- * is a plain trigger, and what it opens is the consumer's to render.
16
- */
17
- onOpenChange?: (open: boolean) => void;
18
- onValueChange?: (value: string) => void;
19
- open?: boolean;
20
- placeholder?: string;
21
- /** Marks the button as the one whose panel is open. Meant for the mobile trigger. */
22
- selected?: boolean;
23
- value?: string;
24
- }
25
- /**
26
- * Search in the header bar: a button that opens a field lying over it, so opening the search moves
27
- * nothing else in the bar.
28
- *
29
- * It is controlled. Hold `open` and `value` yourself, and render the results against `inputRef`.
30
- */
31
- declare const UIHeaderSearch: import('react').ForwardRefExoticComponent<BitkitUIHeaderSearchProps & import('react').RefAttributes<HTMLDivElement>>;
32
- export default UIHeaderSearch;
@@ -1,96 +0,0 @@
1
- import IconMagnifier from "../../icons/IconMagnifier.js";
2
- import BitkitCloseButton from "../BitkitCloseButton/BitkitCloseButton.js";
3
- import { useUIHeaderContext } from "./UIHeaderContext.js";
4
- import { UIHeaderControlBase } from "./UIHeaderControl.js";
5
- import { Box } from "@chakra-ui/react/box";
6
- import { chakra } from "@chakra-ui/react/styled-system";
7
- import { forwardRef, useEffect, useMemo, useRef } from "react";
8
- import { jsx, jsxs } from "react/jsx-runtime";
9
- import { mergeRefs } from "@chakra-ui/react";
10
- //#region lib/components/BitkitUIHeader/UIHeaderSearch.tsx
11
- /**
12
- * Search in the header bar: a button that opens a field lying over it, so opening the search moves
13
- * nothing else in the bar.
14
- *
15
- * It is controlled. Hold `open` and `value` yourself, and render the results against `inputRef`.
16
- */
17
- var UIHeaderSearch = forwardRef((props, ref) => {
18
- const { css, inputRef, label = "Search", onOpenChange, onValueChange, open = false, placeholder, selected, value = "", ...rest } = props;
19
- const { rootRef, styles } = useUIHeaderContext();
20
- const buttonElementRef = useRef(null);
21
- const inputElementRef = useRef(null);
22
- const searchElementRef = useRef(null);
23
- const setInputRef = useMemo(() => mergeRefs(inputElementRef, inputRef), [inputRef]);
24
- const setSearchRef = useMemo(() => mergeRefs(searchElementRef, ref), [ref]);
25
- useEffect(() => {
26
- if (open) inputElementRef.current?.focus();
27
- }, [open]);
28
- useEffect(() => {
29
- if (!open) return void 0;
30
- const dismiss = (event) => {
31
- const target = event.target instanceof Node ? event.target : null;
32
- if (!target || !rootRef.current?.contains(target)) return;
33
- if (searchElementRef.current?.contains(target)) return;
34
- onOpenChange?.(false);
35
- };
36
- document.addEventListener("pointerdown", dismiss);
37
- return () => document.removeEventListener("pointerdown", dismiss);
38
- }, [
39
- onOpenChange,
40
- open,
41
- rootRef
42
- ]);
43
- const handleKeyDown = (event) => {
44
- if (event.key !== "Escape") return;
45
- event.stopPropagation();
46
- buttonElementRef.current?.focus();
47
- onOpenChange?.(false);
48
- };
49
- const handleClear = () => {
50
- onValueChange?.("");
51
- inputElementRef.current?.focus();
52
- };
53
- return /* @__PURE__ */ jsxs(Box, {
54
- ref: setSearchRef,
55
- css: [styles.search, css],
56
- ...rest,
57
- children: [/* @__PURE__ */ jsx(UIHeaderControlBase, {
58
- ref: buttonElementRef,
59
- css: styles.searchButton,
60
- "data-open": open ? "" : void 0,
61
- footprint: "control",
62
- label,
63
- onClick: () => onOpenChange?.(!open),
64
- selected,
65
- children: /* @__PURE__ */ jsx(IconMagnifier, {})
66
- }), /* @__PURE__ */ jsxs(Box, {
67
- css: styles.searchField,
68
- "data-open": open ? "" : void 0,
69
- children: [
70
- /* @__PURE__ */ jsx(IconMagnifier, { css: styles.searchIcon }),
71
- /* @__PURE__ */ jsx(chakra.input, {
72
- ref: setInputRef,
73
- "aria-label": label,
74
- css: styles.searchInput,
75
- onChange: (event) => onValueChange?.(event.target.value),
76
- onKeyDown: handleKeyDown,
77
- placeholder,
78
- tabIndex: open ? void 0 : -1,
79
- type: "search",
80
- value
81
- }),
82
- !!value && /* @__PURE__ */ jsx(BitkitCloseButton, {
83
- "aria-label": "Clear search",
84
- colorVariant: "white",
85
- onClick: handleClear,
86
- size: "md"
87
- })
88
- ]
89
- })]
90
- });
91
- });
92
- UIHeaderSearch.displayName = "BitkitUIHeader.Search";
93
- //#endregion
94
- export { UIHeaderSearch as default };
95
-
96
- //# sourceMappingURL=UIHeaderSearch.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"UIHeaderSearch.js","names":[],"sources":["../../../lib/components/BitkitUIHeader/UIHeaderSearch.tsx"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport { mergeRefs } from '@chakra-ui/react';\nimport { Box, type BoxProps } from '@chakra-ui/react/box';\nimport { chakra } from '@chakra-ui/react/styled-system';\nimport { forwardRef, type KeyboardEvent, type Ref, useEffect, useMemo, useRef } from 'react';\n\nimport { IconMagnifier } from '../../icons';\nimport BitkitCloseButton from '../BitkitCloseButton/BitkitCloseButton';\nimport { useUIHeaderContext } from './UIHeaderContext';\nimport { UIHeaderControlBase } from './UIHeaderControl';\n\nexport interface BitkitUIHeaderSearchProps extends Omit<BoxProps, 'children' | 'onChange'> {\n /**\n * The search field, for anchoring the results to it. The component owns no results list: what a\n * search turns up differs per product, so the consumer renders its own panel against this.\n */\n inputRef?: Ref<HTMLInputElement>;\n /** The accessible name of both the button and the field. */\n label?: string;\n /**\n * Called when the button is pressed, and when Escape closes the field.\n *\n * From `tablet` up this opens the field in place. Below it there is no inline field — the button\n * is a plain trigger, and what it opens is the consumer's to render.\n */\n onOpenChange?: (open: boolean) => void;\n onValueChange?: (value: string) => void;\n open?: boolean;\n placeholder?: string;\n /** Marks the button as the one whose panel is open. Meant for the mobile trigger. */\n selected?: boolean;\n value?: string;\n}\n\n/**\n * Search in the header bar: a button that opens a field lying over it, so opening the search moves\n * nothing else in the bar.\n *\n * It is controlled. Hold `open` and `value` yourself, and render the results against `inputRef`.\n */\nconst UIHeaderSearch = forwardRef<HTMLDivElement, BitkitUIHeaderSearchProps>((props, ref) => {\n const {\n css,\n inputRef,\n label = 'Search',\n onOpenChange,\n onValueChange,\n open = false,\n placeholder,\n selected,\n value = '',\n ...rest\n } = props;\n\n const { rootRef, styles } = useUIHeaderContext();\n\n const buttonElementRef = useRef<HTMLButtonElement>(null);\n const inputElementRef = useRef<HTMLInputElement>(null);\n const searchElementRef = useRef<HTMLDivElement>(null);\n const setInputRef = useMemo(() => mergeRefs(inputElementRef, inputRef), [inputRef]);\n const setSearchRef = useMemo(() => mergeRefs(searchElementRef, ref), [ref]);\n\n useEffect(() => {\n if (open) inputElementRef.current?.focus();\n }, [open]);\n\n // Reaching for another control in the bar is as much a way out of the search as Escape, so the\n // open field gives way to it. Only presses inside the header count: a results panel is rendered\n // by the consumer, somewhere else entirely, and choosing from it must not close the search.\n useEffect(() => {\n if (!open) return undefined;\n\n const dismiss = (event: PointerEvent) => {\n const target = event.target instanceof Node ? event.target : null;\n if (!target || !rootRef.current?.contains(target)) return;\n if (searchElementRef.current?.contains(target)) return;\n onOpenChange?.(false);\n };\n\n document.addEventListener('pointerdown', dismiss);\n return () => document.removeEventListener('pointerdown', dismiss);\n }, [onOpenChange, open, rootRef]);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key !== 'Escape') return;\n event.stopPropagation();\n // Escape leaves the field without going anywhere else, so focus belongs back on the button that\n // opened it. A press on another control moves focus by itself and takes no help.\n buttonElementRef.current?.focus();\n onOpenChange?.(false);\n };\n\n const handleClear = () => {\n onValueChange?.('');\n inputElementRef.current?.focus();\n };\n\n return (\n <Box ref={setSearchRef} css={[styles.search, css]} {...rest}>\n <UIHeaderControlBase\n ref={buttonElementRef}\n css={styles.searchButton}\n data-open={open ? '' : undefined}\n footprint=\"control\"\n label={label}\n onClick={() => onOpenChange?.(!open)}\n selected={selected}\n >\n <IconMagnifier />\n </UIHeaderControlBase>\n <Box css={styles.searchField} data-open={open ? '' : undefined}>\n <IconMagnifier css={styles.searchIcon} />\n {/* No named primitive fits: Chakra's `Input` carries its own recipe, and this field is\n styled entirely by the header's own slot. */}\n <chakra.input\n ref={setInputRef}\n aria-label={label}\n css={styles.searchInput}\n onChange={(event) => onValueChange?.(event.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n // A closed field is invisible but still in the DOM, so keep it out of the tab order.\n tabIndex={open ? undefined : -1}\n type=\"search\"\n value={value}\n />\n {!!value && (\n <BitkitCloseButton aria-label=\"Clear search\" colorVariant=\"white\" onClick={handleClear} size=\"md\" />\n )}\n </Box>\n </Box>\n );\n});\n\nUIHeaderSearch.displayName = 'BitkitUIHeader.Search';\n\nexport default UIHeaderSearch;\n"],"mappings":";;;;;;;;;;;;;;;;AAwCA,IAAM,iBAAiB,YAAuD,OAAO,QAAQ;CAC3F,MAAM,EACJ,KACA,UACA,QAAQ,UACR,cACA,eACA,OAAO,OACP,aACA,UACA,QAAQ,IACR,GAAG,SACD;CAEJ,MAAM,EAAE,SAAS,WAAW,mBAAmB;CAE/C,MAAM,mBAAmB,OAA0B,IAAI;CACvD,MAAM,kBAAkB,OAAyB,IAAI;CACrD,MAAM,mBAAmB,OAAuB,IAAI;CACpD,MAAM,cAAc,cAAc,UAAU,iBAAiB,QAAQ,GAAG,CAAC,QAAQ,CAAC;CAClF,MAAM,eAAe,cAAc,UAAU,kBAAkB,GAAG,GAAG,CAAC,GAAG,CAAC;CAE1E,gBAAgB;EACd,IAAI,MAAM,gBAAgB,SAAS,MAAM;CAC3C,GAAG,CAAC,IAAI,CAAC;CAKT,gBAAgB;EACd,IAAI,CAAC,MAAM,OAAO,KAAA;EAElB,MAAM,WAAW,UAAwB;GACvC,MAAM,SAAS,MAAM,kBAAkB,OAAO,MAAM,SAAS;GAC7D,IAAI,CAAC,UAAU,CAAC,QAAQ,SAAS,SAAS,MAAM,GAAG;GACnD,IAAI,iBAAiB,SAAS,SAAS,MAAM,GAAG;GAChD,eAAe,KAAK;EACtB;EAEA,SAAS,iBAAiB,eAAe,OAAO;EAChD,aAAa,SAAS,oBAAoB,eAAe,OAAO;CAClE,GAAG;EAAC;EAAc;EAAM;CAAO,CAAC;CAEhC,MAAM,iBAAiB,UAA2C;EAChE,IAAI,MAAM,QAAQ,UAAU;EAC5B,MAAM,gBAAgB;EAGtB,iBAAiB,SAAS,MAAM;EAChC,eAAe,KAAK;CACtB;CAEA,MAAM,oBAAoB;EACxB,gBAAgB,EAAE;EAClB,gBAAgB,SAAS,MAAM;CACjC;CAEA,OACE,qBAAC,KAAD;EAAK,KAAK;EAAc,KAAK,CAAC,OAAO,QAAQ,GAAG;EAAG,GAAI;EAAvD,UAAA,CACE,oBAAC,qBAAD;GACE,KAAK;GACL,KAAK,OAAO;GACZ,aAAW,OAAO,KAAK,KAAA;GACvB,WAAU;GACH;GACP,eAAe,eAAe,CAAC,IAAI;GACzB;GAEV,UAAA,oBAAC,eAAD,CAAgB,CAAA;EACG,CAAA,GACrB,qBAAC,KAAD;GAAK,KAAK,OAAO;GAAa,aAAW,OAAO,KAAK,KAAA;GAArD,UAAA;IACE,oBAAC,eAAD,EAAe,KAAK,OAAO,WAAa,CAAA;IAGxC,oBAAC,OAAO,OAAR;KACE,KAAK;KACL,cAAY;KACZ,KAAK,OAAO;KACZ,WAAW,UAAU,gBAAgB,MAAM,OAAO,KAAK;KACvD,WAAW;KACE;KAEb,UAAU,OAAO,KAAA,IAAY;KAC7B,MAAK;KACE;IACR,CAAA;IACA,CAAC,CAAC,SACD,oBAAC,mBAAD;KAAmB,cAAW;KAAe,cAAa;KAAQ,SAAS;KAAa,MAAK;IAAM,CAAA;GAElG;EACF,CAAA,CAAA;;AAET,CAAC;AAED,eAAe,cAAc"}
@@ -1,111 +0,0 @@
1
- import { rem } from "../themeUtils.js";
2
- import { defineRecipe } from "@chakra-ui/react/styled-system";
3
- //#region lib/theme/recipes/UIHeaderButton.recipe.ts
4
- /**
5
- * Only the secondary button is drawn with an outline. The other two keep a transparent border of
6
- * the same width so every variant is the same size.
7
- */
8
- var borderColors = (variant) => variant === "secondary" ? {
9
- base: "sys/ui/header/button/secondary/border",
10
- disabled: "sys/ui/header/button/secondary/border-disabled"
11
- } : {
12
- base: "transparent",
13
- disabled: "transparent"
14
- };
15
- var variantStyles = (variant) => {
16
- const border = borderColors(variant);
17
- return {
18
- background: `sys/ui/header/button/${variant}/bg`,
19
- borderColor: border.base,
20
- color: `sys/ui/header/button/${variant}/fg`,
21
- _hover: {
22
- background: `sys/ui/header/button/${variant}/bg-hover`,
23
- _active: { background: `sys/ui/header/button/${variant}/bg-active` }
24
- },
25
- _active: { background: `sys/ui/header/button/${variant}/bg-active` },
26
- _selected: {
27
- background: `sys/ui/header/button/${variant}/bg-active`,
28
- _hover: { background: `sys/ui/header/button/${variant}/bg-active` }
29
- },
30
- _disabled: {
31
- background: `sys/ui/header/button/${variant}/bg-disabled`,
32
- borderColor: border.disabled,
33
- color: `sys/ui/header/button/${variant}/fg-disabled`,
34
- cursor: "not-allowed"
35
- }
36
- };
37
- };
38
- /**
39
- * An unread marker centred on the button's trailing top corner: a dot with a ring behind it. The
40
- * design draws both inside a 12px box, and neither radius lands on the size scale.
41
- */
42
- var badgeDot = {
43
- background: "sys/ui/header/badge/indigo",
44
- borderRadius: "full",
45
- content: "\"\"",
46
- pointerEvents: "none",
47
- position: "absolute"
48
- };
49
- var badgeStyles = {
50
- _before: {
51
- ...badgeDot,
52
- height: "8",
53
- insetBlockStart: "-4",
54
- insetInlineEnd: "-4",
55
- width: "8"
56
- },
57
- _after: {
58
- ...badgeDot,
59
- height: rem(10),
60
- insetBlockStart: rem(-5),
61
- insetInlineEnd: rem(-5),
62
- opacity: .5,
63
- width: rem(10)
64
- }
65
- };
66
- var uiHeaderButtonRecipe = defineRecipe({
67
- className: "ui-header-button",
68
- base: {
69
- alignItems: "center",
70
- borderRadius: "4",
71
- borderStyle: "solid",
72
- borderWidth: "1",
73
- cursor: "pointer",
74
- display: "inline-flex",
75
- flexShrink: 0,
76
- gap: "4",
77
- height: "32",
78
- justifyContent: "center",
79
- minWidth: "48",
80
- paddingInline: "8",
81
- position: "relative",
82
- textDecoration: "none",
83
- textStyle: "comp/button/sm",
84
- whiteSpace: "nowrap",
85
- _notLast: { marginInlineEnd: "8" },
86
- _disabled: { cursor: "not-allowed" }
87
- },
88
- variants: {
89
- variant: {
90
- primary: variantStyles("primary"),
91
- secondary: variantStyles("secondary"),
92
- tertiary: variantStyles("tertiary")
93
- },
94
- badge: {
95
- idle: badgeStyles,
96
- pulse: {
97
- ...badgeStyles,
98
- _after: {
99
- ...badgeStyles._after,
100
- animation: "ping",
101
- _motionReduce: { animation: "none" }
102
- }
103
- }
104
- }
105
- },
106
- defaultVariants: { variant: "primary" }
107
- });
108
- //#endregion
109
- export { uiHeaderButtonRecipe as default };
110
-
111
- //# sourceMappingURL=UIHeaderButton.recipe.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"UIHeaderButton.recipe.js","names":[],"sources":["../../../lib/theme/recipes/UIHeaderButton.recipe.ts"],"sourcesContent":["import { defineRecipe, type SystemStyleObject } from '@chakra-ui/react/styled-system';\n\nimport { rem } from '../themeUtils';\n\ntype Variant = 'primary' | 'secondary' | 'tertiary';\n\n/**\n * Only the secondary button is drawn with an outline. The other two keep a transparent border of\n * the same width so every variant is the same size.\n */\nconst borderColors = (variant: Variant) =>\n variant === 'secondary'\n ? { base: 'sys/ui/header/button/secondary/border', disabled: 'sys/ui/header/button/secondary/border-disabled' }\n : { base: 'transparent', disabled: 'transparent' };\n\nconst variantStyles = (variant: Variant): SystemStyleObject => {\n const border = borderColors(variant);\n\n return {\n background: `sys/ui/header/button/${variant}/bg`,\n borderColor: border.base,\n color: `sys/ui/header/button/${variant}/fg`,\n // `_hover`/`_active` compile to `:not(:disabled, [data-disabled])`, so they never match a\n // disabled button and `_disabled` wins without `!important`.\n _hover: {\n background: `sys/ui/header/button/${variant}/bg-hover`,\n // Repeat active under hover so clicking while hovering keeps the active styles.\n _active: {\n background: `sys/ui/header/button/${variant}/bg-active`,\n },\n },\n _active: {\n background: `sys/ui/header/button/${variant}/bg-active`,\n },\n // A button that holds a panel open stays pressed while the panel is, hover included — letting\n // hover lighten it would read as the panel having closed.\n _selected: {\n background: `sys/ui/header/button/${variant}/bg-active`,\n _hover: {\n background: `sys/ui/header/button/${variant}/bg-active`,\n },\n },\n _disabled: {\n background: `sys/ui/header/button/${variant}/bg-disabled`,\n borderColor: border.disabled,\n color: `sys/ui/header/button/${variant}/fg-disabled`,\n cursor: 'not-allowed',\n },\n };\n};\n\n/**\n * An unread marker centred on the button's trailing top corner: a dot with a ring behind it. The\n * design draws both inside a 12px box, and neither radius lands on the size scale.\n */\nconst badgeDot: SystemStyleObject = {\n background: 'sys/ui/header/badge/indigo',\n borderRadius: 'full',\n content: '\"\"',\n pointerEvents: 'none',\n position: 'absolute',\n};\n\nconst badgeStyles: SystemStyleObject = {\n _before: {\n ...badgeDot,\n height: '8',\n insetBlockStart: '-4',\n insetInlineEnd: '-4',\n width: '8',\n },\n _after: {\n ...badgeDot,\n height: rem(10),\n insetBlockStart: rem(-5),\n insetInlineEnd: rem(-5),\n opacity: 0.5,\n width: rem(10),\n },\n};\n\nconst uiHeaderButtonRecipe = defineRecipe({\n className: 'ui-header-button',\n base: {\n alignItems: 'center',\n borderRadius: '4',\n borderStyle: 'solid',\n borderWidth: '1',\n cursor: 'pointer',\n display: 'inline-flex',\n flexShrink: 0,\n gap: '4',\n height: '32',\n justifyContent: 'center',\n minWidth: '48',\n paddingInline: '8',\n position: 'relative',\n textDecoration: 'none',\n textStyle: 'comp/button/sm',\n whiteSpace: 'nowrap',\n // The icon controls beside it carry their own padding and sit flush against each other, but a\n // labelled button needs room. A trailing button takes none: the bar's own inset is its room.\n _notLast: {\n marginInlineEnd: '8',\n },\n _disabled: {\n cursor: 'not-allowed',\n },\n },\n variants: {\n variant: {\n primary: variantStyles('primary'),\n secondary: variantStyles('secondary'),\n tertiary: variantStyles('tertiary'),\n },\n badge: {\n idle: badgeStyles,\n pulse: {\n ...badgeStyles,\n _after: {\n ...badgeStyles._after,\n // The system's own ping: the ring expands past the dot and fades out.\n animation: 'ping',\n _motionReduce: {\n animation: 'none',\n },\n },\n },\n },\n },\n defaultVariants: {\n variant: 'primary',\n },\n});\n\nexport default uiHeaderButtonRecipe;\n"],"mappings":";;;;;;;AAUA,IAAM,gBAAgB,YACpB,YAAY,cACR;CAAE,MAAM;CAAyC,UAAU;AAAiD,IAC5G;CAAE,MAAM;CAAe,UAAU;AAAc;AAErD,IAAM,iBAAiB,YAAwC;CAC7D,MAAM,SAAS,aAAa,OAAO;CAEnC,OAAO;EACL,YAAY,wBAAwB,QAAQ;EAC5C,aAAa,OAAO;EACpB,OAAO,wBAAwB,QAAQ;EAGvC,QAAQ;GACN,YAAY,wBAAwB,QAAQ;GAE5C,SAAS,EACP,YAAY,wBAAwB,QAAQ,YAC9C;EACF;EACA,SAAS,EACP,YAAY,wBAAwB,QAAQ,YAC9C;EAGA,WAAW;GACT,YAAY,wBAAwB,QAAQ;GAC5C,QAAQ,EACN,YAAY,wBAAwB,QAAQ,YAC9C;EACF;EACA,WAAW;GACT,YAAY,wBAAwB,QAAQ;GAC5C,aAAa,OAAO;GACpB,OAAO,wBAAwB,QAAQ;GACvC,QAAQ;EACV;CACF;AACF;;;;;AAMA,IAAM,WAA8B;CAClC,YAAY;CACZ,cAAc;CACd,SAAS;CACT,eAAe;CACf,UAAU;AACZ;AAEA,IAAM,cAAiC;CACrC,SAAS;EACP,GAAG;EACH,QAAQ;EACR,iBAAiB;EACjB,gBAAgB;EAChB,OAAO;CACT;CACA,QAAQ;EACN,GAAG;EACH,QAAQ,IAAI,EAAE;EACd,iBAAiB,IAAI,EAAE;EACvB,gBAAgB,IAAI,EAAE;EACtB,SAAS;EACT,OAAO,IAAI,EAAE;CACf;AACF;AAEA,IAAM,uBAAuB,aAAa;CACxC,WAAW;CACX,MAAM;EACJ,YAAY;EACZ,cAAc;EACd,aAAa;EACb,aAAa;EACb,QAAQ;EACR,SAAS;EACT,YAAY;EACZ,KAAK;EACL,QAAQ;EACR,gBAAgB;EAChB,UAAU;EACV,eAAe;EACf,UAAU;EACV,gBAAgB;EAChB,WAAW;EACX,YAAY;EAGZ,UAAU,EACR,iBAAiB,IACnB;EACA,WAAW,EACT,QAAQ,cACV;CACF;CACA,UAAU;EACR,SAAS;GACP,SAAS,cAAc,SAAS;GAChC,WAAW,cAAc,WAAW;GACpC,UAAU,cAAc,UAAU;EACpC;EACA,OAAO;GACL,MAAM;GACN,OAAO;IACL,GAAG;IACH,QAAQ;KACN,GAAG,YAAY;KAEf,WAAW;KACX,eAAe,EACb,WAAW,OACb;IACF;GACF;EACF;CACF;CACA,iBAAiB,EACf,SAAS,UACX;AACF,CAAC"}
@@ -1,11 +0,0 @@
1
- /**
2
- * The height of the header bar — the banner slot below it is not counted, since its height is the
3
- * consumer's content.
4
- *
5
- * A page that pins the header reserves exactly this much room for it, and anything anchored under
6
- * the header starts here: a drawer's backdrop and positioner, a side navigation's
7
- * `insetBlockStart`.
8
- */
9
- export declare const uiHeaderHeight: `${number}rem`;
10
- declare const uiHeaderSlotRecipe: import('@chakra-ui/react').SlotRecipeDefinition<"search" | "badge" | "banner" | "bar" | "root" | "indicator" | "spacer" | "control" | "searchInput" | "actions" | "account" | "navButton" | "accountAvatar" | "accountIcon" | "navButtonBadge" | "navButtonIcon" | "searchButton" | "searchField" | "searchIcon" | "leading" | "logoLink" | "logoBlock", import('@chakra-ui/react').SlotRecipeVariantRecord<"search" | "badge" | "banner" | "bar" | "root" | "indicator" | "spacer" | "control" | "searchInput" | "actions" | "account" | "navButton" | "accountAvatar" | "accountIcon" | "navButtonBadge" | "navButtonIcon" | "searchButton" | "searchField" | "searchIcon" | "leading" | "logoLink" | "logoBlock">>;
11
- export default uiHeaderSlotRecipe;
@@ -1,237 +0,0 @@
1
- import { rem } from "../themeUtils.js";
2
- import { defineSlotRecipe } from "@chakra-ui/react/styled-system";
3
- //#region lib/theme/slot-recipes/UIHeader.recipe.ts
4
- /**
5
- * The height of the header bar — the banner slot below it is not counted, since its height is the
6
- * consumer's content.
7
- *
8
- * A page that pins the header reserves exactly this much room for it, and anything anchored under
9
- * the header starts here: a drawer's backdrop and positioner, a side navigation's
10
- * `insetBlockStart`.
11
- */
12
- var uiHeaderHeight = rem(48);
13
- var SEARCH_FIELD_WIDTH = rem(240);
14
- var SEARCH_FIELD_TINT = "var(--colors-color\\/white\\/20)";
15
- var controlBase = {
16
- background: "sys/ui/header/control/bg",
17
- _hover: {
18
- background: "sys/ui/header/control/bg-hover",
19
- _active: { background: "sys/ui/header/control/bg-active" }
20
- },
21
- _active: { background: "sys/ui/header/control/bg-active" },
22
- _selected: {
23
- background: "sys/ui/header/control/bg-selected",
24
- _hover: {
25
- background: "sys/ui/header/control/bg-selected-hover",
26
- _active: { background: "sys/ui/header/control/bg-active" }
27
- },
28
- _active: { background: "sys/ui/header/control/bg-active" }
29
- },
30
- alignItems: "center",
31
- borderRadius: 0,
32
- color: "icon/on-color",
33
- cursor: "pointer",
34
- display: "flex",
35
- flexShrink: 0,
36
- height: uiHeaderHeight,
37
- justifyContent: "center",
38
- position: "relative",
39
- textDecoration: "none",
40
- _focusVisible: { outlineOffset: "calc(var(--focus-ring-width) * -1)" }
41
- };
42
- var uiHeaderSlotRecipe = defineSlotRecipe({
43
- className: "ui-header",
44
- slots: [
45
- "account",
46
- "accountAvatar",
47
- "accountIcon",
48
- "actions",
49
- "badge",
50
- "banner",
51
- "bar",
52
- "control",
53
- "indicator",
54
- "leading",
55
- "logoLink",
56
- "logoBlock",
57
- "navButton",
58
- "navButtonBadge",
59
- "navButtonIcon",
60
- "root",
61
- "search",
62
- "searchButton",
63
- "searchField",
64
- "searchIcon",
65
- "searchInput",
66
- "spacer"
67
- ],
68
- base: {
69
- root: {
70
- background: "sys/ui/header/bg",
71
- color: "text/on-color",
72
- display: "flex",
73
- flexDirection: "column",
74
- width: "full"
75
- },
76
- bar: {
77
- alignItems: "center",
78
- display: "flex",
79
- flexShrink: 0,
80
- height: uiHeaderHeight,
81
- position: "relative",
82
- tablet: { paddingInlineStart: "20" }
83
- },
84
- leading: {
85
- display: "flex",
86
- flexShrink: 0,
87
- tablet: { display: "none" }
88
- },
89
- spacer: {
90
- flexShrink: 1,
91
- width: "48",
92
- tablet: { display: "none" }
93
- },
94
- logoBlock: {
95
- alignItems: "center",
96
- display: "flex",
97
- flex: 1,
98
- justifyContent: "center",
99
- minWidth: 0,
100
- tablet: { flex: "none" }
101
- },
102
- logoLink: {
103
- borderRadius: "4",
104
- color: "text/on-color",
105
- display: "flex",
106
- marginBlockEnd: rem(3)
107
- },
108
- actions: {
109
- alignItems: "center",
110
- display: "flex",
111
- flexShrink: 0,
112
- marginInlineStart: "auto",
113
- tablet: { paddingInlineEnd: "32" }
114
- },
115
- banner: { width: "full" },
116
- control: {
117
- ...controlBase,
118
- width: "48"
119
- },
120
- account: {
121
- ...controlBase,
122
- width: "48"
123
- },
124
- accountAvatar: {
125
- borderRadius: "full",
126
- display: "none",
127
- overflow: "hidden",
128
- tablet: { display: "inline-flex" }
129
- },
130
- accountIcon: {
131
- display: "block",
132
- tablet: { display: "none" }
133
- },
134
- navButton: {
135
- ...controlBase,
136
- paddingBlock: "8",
137
- paddingInlineEnd: "8",
138
- paddingInlineStart: "12"
139
- },
140
- navButtonBadge: {
141
- alignItems: "flex-start",
142
- background: "sys/ui/header/bg",
143
- borderStartStartRadius: "2",
144
- color: "icon/on-color",
145
- display: "flex",
146
- height: "12",
147
- insetBlockEnd: "8",
148
- insetInlineEnd: "8",
149
- overflow: "hidden",
150
- pointerEvents: "none",
151
- position: "absolute",
152
- width: "16"
153
- },
154
- navButtonIcon: {
155
- flexShrink: 0,
156
- marginBlockStart: rem(-1),
157
- marginInlineStart: "1"
158
- },
159
- badge: {
160
- background: "sys/ui/header/badge/red",
161
- borderRadius: "full",
162
- height: "8",
163
- insetBlockStart: "12",
164
- insetInlineStart: rem(28),
165
- pointerEvents: "none",
166
- position: "absolute",
167
- width: "8"
168
- },
169
- indicator: {
170
- background: "sys/ui/header/control/indicator",
171
- height: "4",
172
- insetBlockEnd: 0,
173
- insetInline: 0,
174
- pointerEvents: "none",
175
- position: "absolute"
176
- },
177
- search: {
178
- display: "flex",
179
- flexShrink: 0,
180
- position: "relative"
181
- },
182
- searchField: {
183
- alignItems: "center",
184
- backgroundColor: "sys/ui/header/bg",
185
- backgroundImage: `linear-gradient(0deg, ${SEARCH_FIELD_TINT} 0%, ${SEARCH_FIELD_TINT} 100%)`,
186
- borderColor: "border/strong",
187
- borderRadius: "4",
188
- borderStyle: "solid",
189
- borderWidth: "1",
190
- display: "none",
191
- gap: "8",
192
- height: "40",
193
- insetBlockStart: "4",
194
- insetInlineEnd: 0,
195
- opacity: 0,
196
- paddingInlineEnd: "12",
197
- paddingInlineStart: "8",
198
- pointerEvents: "none",
199
- position: "absolute",
200
- transitionDuration: "fast",
201
- transitionProperty: "opacity",
202
- transitionTimingFunction: "ease-out",
203
- width: SEARCH_FIELD_WIDTH,
204
- "&:has(input:focus-visible)": { boxShadow: "0 0 0 var(--focus-ring-width) var(--focus-ring-color) inset" },
205
- _open: {
206
- opacity: 1,
207
- pointerEvents: "auto"
208
- },
209
- _motionReduce: { transitionProperty: "none" },
210
- tablet: { display: "flex" }
211
- },
212
- searchButton: { _open: { visibility: "hidden" } },
213
- searchIcon: {
214
- color: "icon/on-color",
215
- flexShrink: 0
216
- },
217
- searchInput: {
218
- background: "transparent",
219
- borderWidth: 0,
220
- color: "text/on-color",
221
- flex: 1,
222
- focusVisibleRing: "none",
223
- minWidth: 0,
224
- padding: 0,
225
- textStyle: "body/lg/regular",
226
- "&::-webkit-search-cancel-button": { display: "none" },
227
- _placeholder: {
228
- color: "text/on-color",
229
- opacity: .6
230
- }
231
- }
232
- }
233
- });
234
- //#endregion
235
- export { uiHeaderSlotRecipe as default, uiHeaderHeight };
236
-
237
- //# sourceMappingURL=UIHeader.recipe.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"UIHeader.recipe.js","names":[],"sources":["../../../lib/theme/slot-recipes/UIHeader.recipe.ts"],"sourcesContent":["import { defineSlotRecipe, type SystemStyleObject } from '@chakra-ui/react/styled-system';\n\nimport { rem } from '../themeUtils';\n\n/**\n * The height of the header bar — the banner slot below it is not counted, since its height is the\n * consumer's content.\n *\n * A page that pins the header reserves exactly this much room for it, and anything anchored under\n * the header starts here: a drawer's backdrop and positioner, a side navigation's\n * `insetBlockStart`.\n */\nexport const uiHeaderHeight = rem(48);\n\n// The design draws the open search field at a fixed width rather than a share of the bar, so it\n// stays the same whatever else sits beside it.\nconst SEARCH_FIELD_WIDTH = rem(240);\n\n// A raw, slash-escaped CSS variable for `color/white/20`: inside a `{colors.…}` reference Chakra\n// reads the first `/` as its color-mix opacity modifier.\nconst SEARCH_FIELD_TINT = 'var(--colors-color\\\\/white\\\\/20)';\n\n/**\n * Background states shared by every control in the bar — the icon buttons, the account button and\n * the mobile navigation button. `selected` is the control whose drawer is open: it keeps a lighter\n * background and grows an indicator along its bottom edge.\n */\nconst controlStates: SystemStyleObject = {\n background: 'sys/ui/header/control/bg',\n _hover: {\n background: 'sys/ui/header/control/bg-hover',\n _active: {\n background: 'sys/ui/header/control/bg-active',\n },\n },\n _active: {\n background: 'sys/ui/header/control/bg-active',\n },\n _selected: {\n background: 'sys/ui/header/control/bg-selected',\n _hover: {\n background: 'sys/ui/header/control/bg-selected-hover',\n _active: {\n background: 'sys/ui/header/control/bg-active',\n },\n },\n _active: {\n background: 'sys/ui/header/control/bg-active',\n },\n },\n};\n\nconst controlBase: SystemStyleObject = {\n ...controlStates,\n alignItems: 'center',\n // Preflight zeroes every border width but not the radius a native button can still draw.\n borderRadius: 0,\n color: 'icon/on-color',\n cursor: 'pointer',\n display: 'flex',\n flexShrink: 0,\n height: uiHeaderHeight,\n justifyContent: 'center',\n position: 'relative',\n textDecoration: 'none',\n // The bar is exactly as tall as its controls, so an outside ring would be clipped at the top and\n // bottom. Pull it inside, the way the side navigation's rows do.\n _focusVisible: {\n outlineOffset: 'calc(var(--focus-ring-width) * -1)',\n },\n};\n\nconst uiHeaderSlotRecipe = defineSlotRecipe({\n className: 'ui-header',\n slots: [\n 'account',\n 'accountAvatar',\n 'accountIcon',\n 'actions',\n 'badge',\n 'banner',\n 'bar',\n 'control',\n 'indicator',\n 'leading',\n 'logoLink',\n 'logoBlock',\n 'navButton',\n 'navButtonBadge',\n 'navButtonIcon',\n 'root',\n 'search',\n 'searchButton',\n 'searchField',\n 'searchIcon',\n 'searchInput',\n 'spacer',\n ],\n base: {\n root: {\n background: 'sys/ui/header/bg',\n color: 'text/on-color',\n display: 'flex',\n flexDirection: 'column',\n width: 'full',\n },\n bar: {\n alignItems: 'center',\n display: 'flex',\n flexShrink: 0,\n height: uiHeaderHeight,\n position: 'relative',\n tablet: {\n paddingInlineStart: '20',\n },\n },\n leading: {\n display: 'flex',\n flexShrink: 0,\n tablet: {\n display: 'none',\n },\n },\n // What balances the trailing controls against the leading slot, so the logo between them lands\n // in the middle of the bar. The design draws it at a fixed width; it is the first thing to give\n // when the controls need more room than that leaves.\n spacer: {\n flexShrink: 1,\n width: '48',\n tablet: {\n display: 'none',\n },\n },\n // On mobile the logo is centred in what the two flanks leave, which the spacer has evened out.\n // Controls heavier than the spacer can even out — an Ask AI button among them — take their room\n // from this block, and the logo moves with it rather than being overlapped.\n logoBlock: {\n alignItems: 'center',\n display: 'flex',\n flex: 1,\n justifyContent: 'center',\n minWidth: 0,\n tablet: {\n flex: 'none',\n },\n },\n logoLink: {\n borderRadius: '4',\n color: 'text/on-color',\n display: 'flex',\n // Optical centring: the wordmark reads as sitting low in the bar when it is centred by its\n // bounding box, so the design lifts it. No size token at this scale.\n marginBlockEnd: rem(3),\n },\n actions: {\n alignItems: 'center',\n display: 'flex',\n flexShrink: 0,\n // The logo block only grows on mobile, so on desktop this is what pushes the actions to the\n // trailing edge.\n marginInlineStart: 'auto',\n tablet: {\n paddingInlineEnd: '32',\n },\n },\n banner: {\n width: 'full',\n },\n control: {\n ...controlBase,\n width: '48',\n },\n account: {\n ...controlBase,\n width: '48',\n },\n // The account button carries the user's avatar on desktop and a plain icon on mobile. Both are\n // rendered and one is hidden, so the button never has to know the viewport: no breakpoint hook,\n // and no wrong-layout first paint.\n accountAvatar: {\n // The design draws the account as a circle whatever is in it, while the avatar's own shape\n // is only round when it holds a picture. Clipping covers the initials fallback too.\n borderRadius: 'full',\n display: 'none',\n overflow: 'hidden',\n tablet: {\n display: 'inline-flex',\n },\n },\n accountIcon: {\n display: 'block',\n tablet: {\n display: 'none',\n },\n },\n navButton: {\n ...controlBase,\n paddingBlock: '8',\n paddingInlineEnd: '8',\n paddingInlineStart: '12',\n },\n // A notch of the header's own background punched into the corner of the workspace avatar, with\n // the menu icon inside it.\n navButtonBadge: {\n alignItems: 'flex-start',\n background: 'sys/ui/header/bg',\n borderStartStartRadius: '2',\n color: 'icon/on-color',\n display: 'flex',\n height: '12',\n insetBlockEnd: '8',\n insetInlineEnd: '8',\n overflow: 'hidden',\n pointerEvents: 'none',\n position: 'absolute',\n width: '16',\n },\n navButtonIcon: {\n flexShrink: 0,\n // The notch shows the icon's top edge only, and the design nudges it a pixel to sit flush\n // with the avatar's corner.\n marginBlockStart: rem(-1),\n marginInlineStart: '1',\n },\n badge: {\n background: 'sys/ui/header/badge/red',\n borderRadius: 'full',\n height: '8',\n // The top trailing corner of a 24px icon centred in a 48px control. The inline offset is a\n // measurement of that geometry rather than a spacing step, so no token lands on it.\n insetBlockStart: '12',\n insetInlineStart: rem(28),\n pointerEvents: 'none',\n position: 'absolute',\n width: '8',\n },\n indicator: {\n background: 'sys/ui/header/control/indicator',\n height: '4',\n insetBlockEnd: 0,\n insetInline: 0,\n pointerEvents: 'none',\n position: 'absolute',\n },\n search: {\n display: 'flex',\n flexShrink: 0,\n position: 'relative',\n },\n // The field lies over its own button rather than in the flow, so opening it moves nothing else\n // in the bar. Below `tablet` there is no inline field at all: the button opens whatever the\n // consumer puts the search in.\n searchField: {\n alignItems: 'center',\n // The design paints the field as the page surface at a fifth of its opacity, and there is no\n // `sys/ui/header` token for it. It is laid over the bar's own colour rather than blended with\n // it, so the open field is opaque: the button it covers and whatever the consumer put beside\n // it must not read through.\n backgroundColor: 'sys/ui/header/bg',\n backgroundImage: `linear-gradient(0deg, ${SEARCH_FIELD_TINT} 0%, ${SEARCH_FIELD_TINT} 100%)`,\n borderColor: 'border/strong',\n borderRadius: '4',\n borderStyle: 'solid',\n borderWidth: '1',\n display: 'none',\n gap: '8',\n height: '40',\n // Centres the 40px field against the 48px bar.\n insetBlockStart: '4',\n insetInlineEnd: 0,\n opacity: 0,\n paddingInlineEnd: '12',\n paddingInlineStart: '8',\n pointerEvents: 'none',\n position: 'absolute',\n transitionDuration: 'fast',\n transitionProperty: 'opacity',\n transitionTimingFunction: 'ease-out',\n width: SEARCH_FIELD_WIDTH,\n // The field is the control, so it takes the ring the input would have drawn inside it.\n '&:has(input:focus-visible)': {\n boxShadow: '0 0 0 var(--focus-ring-width) var(--focus-ring-color) inset',\n },\n _open: {\n opacity: 1,\n pointerEvents: 'auto',\n },\n _motionReduce: {\n transitionProperty: 'none',\n },\n tablet: {\n display: 'flex',\n },\n },\n // The open field covers its own button, so the button stops being something to look at, click\n // or tab to. It keeps its space: the field is positioned against it.\n searchButton: {\n _open: {\n visibility: 'hidden',\n },\n },\n searchIcon: {\n color: 'icon/on-color',\n flexShrink: 0,\n },\n searchInput: {\n background: 'transparent',\n borderWidth: 0,\n color: 'text/on-color',\n flex: 1,\n focusVisibleRing: 'none',\n minWidth: 0,\n padding: 0,\n textStyle: 'body/lg/regular',\n // `type=\"search\"` draws a clear button of its own, which would sit beside ours.\n '&::-webkit-search-cancel-button': { display: 'none' },\n _placeholder: {\n color: 'text/on-color',\n opacity: 0.6,\n },\n },\n },\n});\n\nexport default uiHeaderSlotRecipe;\n"],"mappings":"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"}