@fairmint/ui 0.3.21 → 0.3.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/generic/AgentSuggestion/AgentSuggestion.cjs +47 -46
- package/dist/components/generic/AgentSuggestion/AgentSuggestion.cjs.map +1 -1
- package/dist/components/generic/AgentSuggestion/AgentSuggestion.d.ts +1 -1
- package/dist/components/generic/AgentSuggestion/AgentSuggestion.d.ts.map +1 -1
- package/dist/components/generic/AgentSuggestion/AgentSuggestion.js +47 -46
- package/dist/components/generic/AgentSuggestion/AgentSuggestion.js.map +1 -1
- package/dist/components/generic/Banner/Banner.cjs +1 -1
- package/dist/components/generic/Banner/Banner.cjs.map +1 -1
- package/dist/components/generic/Banner/Banner.js +1 -1
- package/dist/components/generic/Banner/Banner.js.map +1 -1
- package/dist/components/generic/TaskInboxPopover/TaskInboxPopover.cjs +72 -0
- package/dist/components/generic/TaskInboxPopover/TaskInboxPopover.cjs.map +1 -0
- package/dist/components/generic/TaskInboxPopover/TaskInboxPopover.d.ts +36 -0
- package/dist/components/generic/TaskInboxPopover/TaskInboxPopover.d.ts.map +1 -0
- package/dist/components/generic/TaskInboxPopover/TaskInboxPopover.js +72 -0
- package/dist/components/generic/TaskInboxPopover/TaskInboxPopover.js.map +1 -0
- package/dist/components/generic/TaskRow/TaskRow.cjs +31 -6
- package/dist/components/generic/TaskRow/TaskRow.cjs.map +1 -1
- package/dist/components/generic/TaskRow/TaskRow.d.ts.map +1 -1
- package/dist/components/generic/TaskRow/TaskRow.js +31 -6
- package/dist/components/generic/TaskRow/TaskRow.js.map +1 -1
- package/dist/components/primitives/Popover/Popover.cjs +13 -0
- package/dist/components/primitives/Popover/Popover.cjs.map +1 -0
- package/dist/components/primitives/Popover/Popover.d.ts +19 -0
- package/dist/components/primitives/Popover/Popover.d.ts.map +1 -0
- package/dist/components/primitives/Popover/Popover.js +13 -0
- package/dist/components/primitives/Popover/Popover.js.map +1 -0
- package/dist/components/primitives/index.d.ts +1 -0
- package/dist/components/primitives/index.d.ts.map +1 -1
- package/dist/components/primitives/muiIcons.d.ts +2 -0
- package/dist/components/primitives/muiIcons.d.ts.map +1 -1
- package/dist/fairmint-ui.cjs +4 -0
- package/dist/fairmint-ui.cjs.map +1 -1
- package/dist/fairmint-ui.js +4 -0
- package/dist/fairmint-ui.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/mui-icons.cjs +10 -14
- package/dist/mui-icons.cjs.map +1 -1
- package/dist/mui-icons.js +10 -14
- package/dist/mui-icons.js.map +1 -1
- package/dist/node_modules/@floating-ui/core/dist/floating-ui.core.js +1 -1
- package/dist/node_modules/@floating-ui/dom/dist/floating-ui.dom.js +1 -1
- package/dist/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.js +1 -1
- package/dist/notify.cjs +1 -1
- package/dist/notify.cjs.map +1 -1
- package/dist/notify.js +1 -1
- package/dist/notify.js.map +1 -1
- package/dist/theme/colors.cjs.map +1 -1
- package/dist/theme/colors.d.ts +16 -0
- package/dist/theme/colors.d.ts.map +1 -1
- package/dist/theme/colors.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Banner.js","sources":["../../../../src/components/generic/Banner/Banner.tsx"],"sourcesContent":["import type { AriaRole, CSSProperties, ReactNode } from \"react\";\nimport { fairmintVars, fontSizes, radii, spacing } from \"../../../theme\";\nimport { colors } from \"../../../theme/colors\";\nimport { Badge } from \"../../primitives/Badge/Badge\";\nimport { Button, type ButtonProps } from \"../../primitives/Button/Button\";\nimport { Box, Group, Text, ThemeIcon } from \"../../primitives/layout\";\n\nexport type BannerTone = \"brand\" | \"neutral\" | \"info\" | \"success\" | \"warning\" | \"error\";\nexport type BannerPresentation = \"inline\" | \"page-level\";\n\nexport interface BannerActionProps extends Omit<ButtonProps, \"children\" | \"color\" | \"variant\"> {\n /** Visible action label. */\n label: ReactNode;\n}\n\nexport type BannerActions =\n | readonly [BannerActionProps]\n | readonly [BannerActionProps, BannerActionProps];\n\nexport interface BannerProps {\n /** Primary message. Omit when the banner is description-only; set `ariaLabel` for accessibility. */\n title?: ReactNode;\n /** Supporting context. Omit for a title-only banner. */\n description?: ReactNode;\n /** Semantic meaning and visual treatment. @default \"brand\" */\n tone?: BannerTone;\n /** Inline content callout or full-width page-edge treatment. @default \"inline\" */\n presentation?: BannerPresentation;\n /** Icon shown beside the title. Pass `null` to hide. Default is a 20px tone icon. */\n icon?: ReactNode | null;\n /** Optional badge label displayed beside the title. */\n badgeLabel?: ReactNode;\n /** Optional standardized CTA. */\n action?: BannerActionProps;\n /** Up to two CTAs in visual order: secondary first, primary last. */\n actions?: BannerActions;\n /** Override the default accessible role. Error defaults to alert; other tones use status. */\n role?: AriaRole;\n /** Accessible label for the banner region. Defaults to the string title when possible. */\n ariaLabel?: string;\n className?: string;\n style?: CSSProperties;\n}\n\nconst TONE_COLORS = {\n brand: colors.primary,\n neutral: colors.neutral,\n info: colors.info,\n success: colors.success,\n warning: colors.warning,\n error: colors.error,\n} as const;\n\nconst TONE_TOKENS = {\n brand: {\n background: fairmintVars.colorBgBrandSubtle,\n border: fairmintVars.colorBorderFocus,\n icon: fairmintVars.colorBrandPrimary,\n },\n neutral: {\n background: fairmintVars.colorBgSurfaceSecondary,\n border: fairmintVars.colorBorderDefault,\n icon: fairmintVars.colorIconSecondary,\n },\n info: {\n background: fairmintVars.colorInfoBg,\n border: fairmintVars.colorInfoBorder,\n icon: fairmintVars.colorInfoText,\n },\n success: {\n background: fairmintVars.colorSuccessBg,\n border: fairmintVars.colorSuccessBorder,\n icon: fairmintVars.colorSuccessText,\n },\n warning: {\n background: fairmintVars.colorWarningBg,\n border: fairmintVars.colorWarningBorder,\n icon: fairmintVars.colorWarningText,\n },\n error: {\n background: fairmintVars.colorErrorBg,\n border: fairmintVars.colorErrorBorder,\n icon: fairmintVars.colorErrorText,\n },\n} as const;\n\nconst DefaultStatusIcon = ({ tone }: { tone: BannerTone }) => {\n const commonProps = {\n width: 20,\n height: 20,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 1.75,\n strokeLinecap: \"round\" as const,\n strokeLinejoin: \"round\" as const,\n \"aria-hidden\": true,\n };\n\n if (tone === \"success\") {\n return (\n <svg {...commonProps}>\n <title>Success</title>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"m8.5 12 2.25 2.25L15.75 9\" />\n </svg>\n );\n }\n\n if (tone === \"warning\") {\n return (\n <svg {...commonProps}>\n <title>Warning</title>\n <path d=\"M10.3 4.2 2.6 18a2 2 0 0 0 1.75 3h15.3a2 2 0 0 0 1.75-3L13.7 4.2a2 2 0 0 0-3.4 0Z\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </svg>\n );\n }\n\n if (tone === \"error\") {\n return (\n <svg {...commonProps}>\n <title>Error</title>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"m9 9 6 6\" />\n <path d=\"m15 9-6 6\" />\n </svg>\n );\n }\n\n return (\n <svg {...commonProps}>\n <title>Information</title>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 11v5\" />\n <path d=\"M12 8h.01\" />\n </svg>\n );\n};\n\nconst surfaceProps = (tone: BannerTone, presentation: BannerPresentation) => {\n const tokens = TONE_TOKENS[tone];\n\n if (presentation === \"page-level\") {\n return {\n style: {\n backgroundColor: tokens.background,\n borderRadius: 0,\n } satisfies CSSProperties,\n };\n }\n\n return {\n style: {\n backgroundColor: tokens.background,\n border: `1px solid ${tokens.border}`,\n borderRadius: radii.lg,\n } satisfies CSSProperties,\n };\n};\n\n/**\n * Banner titles always use primary text color regardless of tone or\n * presentation — tinted semantic shades are reserved for the fill/border/icon,\n * keeping title contrast consistent (and WCAG AA) across color schemes.\n */\nconst titleColor = () => fairmintVars.colorTextPrimary;\n\nconst actionVariant = (tone: BannerTone, isSecondary: boolean): ButtonProps[\"variant\"] => {\n if (isSecondary) return \"outline\";\n if (tone === \"brand\") return \"light\";\n if (tone === \"neutral\") return \"outline\";\n return \"filled\";\n};\n\ninterface BannerLayoutOptions {\n hasIcon: boolean;\n hasTitle: boolean;\n hasDescription: boolean;\n hasActions: boolean;\n}\n\nconst getBannerLayout = ({\n hasActions,\n hasDescription,\n hasIcon,\n hasTitle,\n}: BannerLayoutOptions) => {\n const mobileColumns = hasIcon ? \"20px minmax(0, 1fr)\" : \"minmax(0, 1fr)\";\n const desktopContentColumns = hasIcon ? [\"20px\"] : [];\n\n if (hasTitle || hasDescription) {\n desktopContentColumns.push(\"minmax(0, 1fr)\");\n }\n\n if (hasActions) {\n desktopContentColumns.push(\"auto\");\n }\n\n const mobileRows: string[] = [];\n if (hasIcon && hasTitle) mobileRows.push('\"icon title\"');\n else if (hasIcon) mobileRows.push('\"icon icon\"');\n else if (hasTitle) mobileRows.push('\"title\"');\n\n if (hasDescription) mobileRows.push(hasIcon ? '\"description description\"' : '\"description\"');\n if (hasActions) mobileRows.push(hasIcon ? '\"actions actions\"' : '\"actions\"');\n\n const desktopRows: string[] = [];\n const actionCell = hasActions ? \" actions\" : \"\";\n if (hasIcon && hasTitle && hasDescription) {\n desktopRows.push(`\"icon title${actionCell}\"`, `\"icon description${actionCell}\"`);\n } else if (hasIcon && hasTitle) {\n desktopRows.push(`\"icon title${actionCell}\"`);\n } else if (hasIcon && hasDescription) {\n desktopRows.push(`\"icon description${actionCell}\"`);\n } else if (hasIcon) {\n desktopRows.push(`\"icon${hasActions ? \" actions\" : \"\"}\"`);\n } else if (hasTitle && hasDescription) {\n desktopRows.push(`\"title${actionCell}\"`, `\"description${actionCell}\"`);\n } else if (hasTitle) {\n desktopRows.push(`\"title${actionCell}\"`);\n } else if (hasDescription) {\n desktopRows.push(`\"description${actionCell}\"`);\n } else if (hasActions) {\n desktopRows.push('\"actions\"');\n }\n\n return {\n gridTemplateAreas: {\n base: mobileRows.join(\" \"),\n sm: desktopRows.join(\" \"),\n },\n gridTemplateColumns: {\n base: mobileColumns,\n sm: desktopContentColumns.join(\" \") || \"auto\",\n },\n };\n};\n\nconst descriptionTextProps = {\n size: \"sm\" as const,\n c: fairmintVars.colorTextSecondary,\n style: { lineHeight: 1.4 },\n};\n\nfunction BannerDescription({ children }: { children: ReactNode }) {\n if (typeof children === \"string\" || typeof children === \"number\") {\n return <Text {...descriptionTextProps}>{children}</Text>;\n }\n\n return (\n <Box\n c={fairmintVars.colorTextSecondary}\n style={{\n fontSize: fontSizes.sm,\n lineHeight: 1.4,\n }}\n >\n {children}\n </Box>\n );\n}\n\n/**\n * Persistent contextual guidance with semantic inline and page-level presentations.\n * Position page-level banners in the consuming layout; the component does not use fixed positioning.\n */\nexport function Banner({\n action,\n ariaLabel,\n badgeLabel,\n className,\n description,\n icon,\n actions,\n presentation = \"inline\",\n role,\n style,\n title,\n tone = \"brand\",\n}: BannerProps) {\n const color = TONE_COLORS[tone];\n const tokens = TONE_TOKENS[tone];\n const iconNode = icon === undefined ? <DefaultStatusIcon tone={tone} /> : icon;\n const resolvedActions = actions ?? (action === undefined ? [] : [action]);\n const resolvedRole = role ?? (tone === \"error\" ? \"alert\" : \"status\");\n const resolvedAriaLabel = ariaLabel ?? (typeof title === \"string\" ? title : undefined);\n const surface = surfaceProps(tone, presentation);\n const layout = getBannerLayout({\n hasActions: resolvedActions.length > 0,\n hasDescription: description !== undefined,\n hasIcon: iconNode !== null,\n hasTitle: title !== undefined || badgeLabel !== undefined,\n });\n\n return (\n <Box\n aria-label={resolvedAriaLabel}\n className={className}\n data-presentation={presentation}\n data-tone={tone}\n role={resolvedRole}\n pl=\"md\"\n pr=\"lg\"\n py=\"md\"\n style={{\n boxSizing: \"border-box\",\n width: \"100%\",\n ...surface.style,\n ...style,\n }}\n sx={{\n display: \"grid\",\n // Match Alert: icon→copy uses spacing.md; title→body is tighter than xs.\n columnGap: spacing.md,\n rowGap: \"0.25rem\",\n ...layout,\n }}\n >\n {iconNode !== null && (\n <ThemeIcon\n aria-hidden\n color={color}\n radius=\"sm\"\n size={20}\n variant=\"transparent\"\n style={{\n color: tokens.icon,\n gridArea: \"icon\",\n // Top-left of the container — matches Alert; stays with the title\n // when description/actions stretch the grid row span.\n alignSelf: \"start\",\n }}\n >\n {iconNode}\n </ThemeIcon>\n )}\n\n {(title !== undefined || badgeLabel !== undefined) && (\n <Group\n align=\"center\"\n gap=\"xs\"\n wrap=\"wrap\"\n style={{ gridArea: \"title\", minWidth: 0, overflowWrap: \"anywhere\" }}\n >\n {title !== undefined && (\n <Text\n fw={600}\n size=\"md\"\n c={titleColor()}\n style={{ lineHeight: 1.35, minWidth: 0, overflowWrap: \"anywhere\" }}\n >\n {title}\n </Text>\n )}\n {badgeLabel !== undefined && (\n <Badge color={color} size=\"sm\" variant=\"light\">\n {badgeLabel}\n </Badge>\n )}\n </Group>\n )}\n\n {description !== undefined && (\n <Box style={{ gridArea: \"description\", minWidth: 0, overflowWrap: \"anywhere\" }}>\n <BannerDescription>{description}</BannerDescription>\n </Box>\n )}\n\n {resolvedActions.length > 0 && (\n <Box\n sx={{\n display: \"flex\",\n flexDirection: { base: \"column\", sm: \"row\" },\n alignItems: \"stretch\",\n justifyContent: \"flex-end\",\n gap: spacing.xs,\n minWidth: 0,\n width: { base: \"100%\", sm: \"max-content\" },\n maxWidth: \"100%\",\n }}\n style={{ gridArea: \"actions\", alignSelf: \"center\", justifySelf: \"end\" }}\n >\n {resolvedActions.map(({ label, size, ...buttonProps }, index) => (\n <Button\n key={buttonProps.id ?? (typeof label === \"string\" ? label : `banner-action-${index}`)}\n {...buttonProps}\n color={color}\n size={size ?? \"sm\"}\n variant={actionVariant(tone, index < resolvedActions.length - 1)}\n style={{\n ...buttonProps.style,\n boxSizing: \"border-box\",\n flex: \"0 1 auto\",\n maxWidth: \"100%\",\n overflowWrap: \"anywhere\",\n whiteSpace: \"normal\",\n width: \"100%\",\n }}\n >\n {label}\n </Button>\n ))}\n </Box>\n )}\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Banner.js","sources":["../../../../src/components/generic/Banner/Banner.tsx"],"sourcesContent":["import type { AriaRole, CSSProperties, ReactNode } from \"react\";\nimport { fairmintVars, fontSizes, radii, spacing } from \"../../../theme\";\nimport { colors } from \"../../../theme/colors\";\nimport { Badge } from \"../../primitives/Badge/Badge\";\nimport { Button, type ButtonProps } from \"../../primitives/Button/Button\";\nimport { Box, Group, Text, ThemeIcon } from \"../../primitives/layout\";\n\nexport type BannerTone = \"brand\" | \"neutral\" | \"info\" | \"success\" | \"warning\" | \"error\";\nexport type BannerPresentation = \"inline\" | \"page-level\";\n\nexport interface BannerActionProps extends Omit<ButtonProps, \"children\" | \"color\" | \"variant\"> {\n /** Visible action label. */\n label: ReactNode;\n}\n\nexport type BannerActions =\n | readonly [BannerActionProps]\n | readonly [BannerActionProps, BannerActionProps];\n\nexport interface BannerProps {\n /** Primary message. Omit when the banner is description-only; set `ariaLabel` for accessibility. */\n title?: ReactNode;\n /** Supporting context. Omit for a title-only banner. */\n description?: ReactNode;\n /** Semantic meaning and visual treatment. @default \"brand\" */\n tone?: BannerTone;\n /** Inline content callout or full-width page-edge treatment. @default \"inline\" */\n presentation?: BannerPresentation;\n /** Icon shown beside the title. Pass `null` to hide. Default is a 20px tone icon. */\n icon?: ReactNode | null;\n /** Optional badge label displayed beside the title. */\n badgeLabel?: ReactNode;\n /** Optional standardized CTA. */\n action?: BannerActionProps;\n /** Up to two CTAs in visual order: secondary first, primary last. */\n actions?: BannerActions;\n /** Override the default accessible role. Error defaults to alert; other tones use status. */\n role?: AriaRole;\n /** Accessible label for the banner region. Defaults to the string title when possible. */\n ariaLabel?: string;\n className?: string;\n style?: CSSProperties;\n}\n\nconst TONE_COLORS = {\n brand: colors.primary,\n neutral: colors.neutral,\n info: colors.info,\n success: colors.success,\n warning: colors.warning,\n error: colors.error,\n} as const;\n\nconst TONE_TOKENS = {\n brand: {\n background: fairmintVars.colorBgBrandSubtle,\n border: fairmintVars.colorBorderFocus,\n icon: fairmintVars.colorBrandPrimary,\n },\n neutral: {\n background: fairmintVars.colorBgSurfaceSecondary,\n border: fairmintVars.colorBorderDefault,\n icon: fairmintVars.colorIconSecondary,\n },\n info: {\n background: fairmintVars.colorInfoBg,\n border: fairmintVars.colorInfoBorder,\n icon: fairmintVars.colorInfoText,\n },\n success: {\n background: fairmintVars.colorSuccessBg,\n border: fairmintVars.colorSuccessBorder,\n icon: fairmintVars.colorSuccessText,\n },\n warning: {\n background: fairmintVars.colorWarningBg,\n border: fairmintVars.colorWarningBorder,\n icon: fairmintVars.colorWarningText,\n },\n error: {\n background: fairmintVars.colorErrorBg,\n border: fairmintVars.colorErrorBorder,\n icon: fairmintVars.colorErrorText,\n },\n} as const;\n\nconst DefaultStatusIcon = ({ tone }: { tone: BannerTone }) => {\n const commonProps = {\n width: 20,\n height: 20,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 1.75,\n strokeLinecap: \"round\" as const,\n strokeLinejoin: \"round\" as const,\n \"aria-hidden\": true,\n };\n\n if (tone === \"success\") {\n return (\n <svg {...commonProps}>\n <title>Success</title>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"m8.5 12 2.25 2.25L15.75 9\" />\n </svg>\n );\n }\n\n if (tone === \"warning\") {\n return (\n <svg {...commonProps}>\n <title>Warning</title>\n <path d=\"M10.3 4.2 2.6 18a2 2 0 0 0 1.75 3h15.3a2 2 0 0 0 1.75-3L13.7 4.2a2 2 0 0 0-3.4 0Z\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </svg>\n );\n }\n\n if (tone === \"error\") {\n return (\n <svg {...commonProps}>\n <title>Error</title>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"m9 9 6 6\" />\n <path d=\"m15 9-6 6\" />\n </svg>\n );\n }\n\n return (\n <svg {...commonProps}>\n <title>Information</title>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 11v5\" />\n <path d=\"M12 8h.01\" />\n </svg>\n );\n};\n\nconst surfaceProps = (tone: BannerTone, presentation: BannerPresentation) => {\n const tokens = TONE_TOKENS[tone];\n\n if (presentation === \"page-level\") {\n return {\n style: {\n backgroundColor: tokens.background,\n borderRadius: 0,\n } satisfies CSSProperties,\n };\n }\n\n return {\n style: {\n backgroundColor: tokens.background,\n border: `1px solid ${tokens.border}`,\n borderRadius: radii.lg,\n } satisfies CSSProperties,\n };\n};\n\n/**\n * Banner titles always use primary text color regardless of tone or\n * presentation — tinted semantic shades are reserved for the fill/border/icon,\n * keeping title contrast consistent (and WCAG AA) across color schemes.\n */\nconst titleColor = () => fairmintVars.colorTextPrimary;\n\nconst actionVariant = (tone: BannerTone, isSecondary: boolean): ButtonProps[\"variant\"] => {\n if (isSecondary) return \"outline\";\n if (tone === \"brand\") return \"light\";\n if (tone === \"neutral\") return \"outline\";\n return \"filled\";\n};\n\ninterface BannerLayoutOptions {\n hasIcon: boolean;\n hasTitle: boolean;\n hasDescription: boolean;\n hasActions: boolean;\n}\n\nconst getBannerLayout = ({\n hasActions,\n hasDescription,\n hasIcon,\n hasTitle,\n}: BannerLayoutOptions) => {\n const mobileColumns = hasIcon ? \"20px minmax(0, 1fr)\" : \"minmax(0, 1fr)\";\n const desktopContentColumns = hasIcon ? [\"20px\"] : [];\n\n if (hasTitle || hasDescription) {\n desktopContentColumns.push(\"minmax(0, 1fr)\");\n }\n\n if (hasActions) {\n desktopContentColumns.push(\"auto\");\n }\n\n const mobileRows: string[] = [];\n if (hasIcon && hasTitle) mobileRows.push('\"icon title\"');\n else if (hasIcon) mobileRows.push('\"icon icon\"');\n else if (hasTitle) mobileRows.push('\"title\"');\n\n if (hasDescription) mobileRows.push(hasIcon ? '\"description description\"' : '\"description\"');\n if (hasActions) mobileRows.push(hasIcon ? '\"actions actions\"' : '\"actions\"');\n\n const desktopRows: string[] = [];\n const actionCell = hasActions ? \" actions\" : \"\";\n if (hasIcon && hasTitle && hasDescription) {\n desktopRows.push(`\"icon title${actionCell}\"`, `\"icon description${actionCell}\"`);\n } else if (hasIcon && hasTitle) {\n desktopRows.push(`\"icon title${actionCell}\"`);\n } else if (hasIcon && hasDescription) {\n desktopRows.push(`\"icon description${actionCell}\"`);\n } else if (hasIcon) {\n desktopRows.push(`\"icon${hasActions ? \" actions\" : \"\"}\"`);\n } else if (hasTitle && hasDescription) {\n desktopRows.push(`\"title${actionCell}\"`, `\"description${actionCell}\"`);\n } else if (hasTitle) {\n desktopRows.push(`\"title${actionCell}\"`);\n } else if (hasDescription) {\n desktopRows.push(`\"description${actionCell}\"`);\n } else if (hasActions) {\n desktopRows.push('\"actions\"');\n }\n\n return {\n gridTemplateAreas: {\n base: mobileRows.join(\" \"),\n sm: desktopRows.join(\" \"),\n },\n gridTemplateColumns: {\n base: mobileColumns,\n sm: desktopContentColumns.join(\" \") || \"auto\",\n },\n };\n};\n\nconst descriptionTextProps = {\n size: \"sm\" as const,\n c: fairmintVars.colorTextSecondary,\n style: { lineHeight: 1.4 },\n};\n\nfunction BannerDescription({ children }: { children: ReactNode }) {\n if (typeof children === \"string\" || typeof children === \"number\") {\n return <Text {...descriptionTextProps}>{children}</Text>;\n }\n\n return (\n <Box\n c={fairmintVars.colorTextSecondary}\n style={{\n fontSize: fontSizes.sm,\n lineHeight: 1.4,\n }}\n >\n {children}\n </Box>\n );\n}\n\n/**\n * Persistent contextual guidance with semantic inline and page-level presentations.\n * Position page-level banners in the consuming layout; the component does not use fixed positioning.\n */\nexport function Banner({\n action,\n ariaLabel,\n badgeLabel,\n className,\n description,\n icon,\n actions,\n presentation = \"inline\",\n role,\n style,\n title,\n tone = \"brand\",\n}: BannerProps) {\n const color = TONE_COLORS[tone];\n const tokens = TONE_TOKENS[tone];\n const iconNode = icon === undefined ? <DefaultStatusIcon tone={tone} /> : icon;\n const resolvedActions = actions ?? (action === undefined ? [] : [action]);\n const resolvedRole = role ?? (tone === \"error\" ? \"alert\" : \"status\");\n const resolvedAriaLabel = ariaLabel ?? (typeof title === \"string\" ? title : undefined);\n const surface = surfaceProps(tone, presentation);\n const layout = getBannerLayout({\n hasActions: resolvedActions.length > 0,\n hasDescription: description !== undefined,\n hasIcon: iconNode !== null,\n hasTitle: title !== undefined || badgeLabel !== undefined,\n });\n\n return (\n <Box\n aria-label={resolvedAriaLabel}\n className={className}\n data-presentation={presentation}\n data-tone={tone}\n role={resolvedRole}\n pl=\"md\"\n pr=\"lg\"\n py=\"md\"\n style={{\n boxSizing: \"border-box\",\n width: \"100%\",\n ...surface.style,\n ...style,\n }}\n sx={{\n display: \"grid\",\n // Match Alert: icon→copy uses spacing.md; title→body is tighter than xs.\n columnGap: spacing.md,\n rowGap: \"0.25rem\",\n ...layout,\n }}\n >\n {iconNode !== null && (\n <ThemeIcon\n aria-hidden\n color={color}\n radius=\"sm\"\n size={20}\n variant=\"transparent\"\n style={{\n color: tokens.icon,\n gridArea: \"icon\",\n // Top-left of the container — matches Alert; stays with the title\n // when description/actions stretch the grid row span.\n alignSelf: \"start\",\n }}\n >\n {iconNode}\n </ThemeIcon>\n )}\n\n {(title !== undefined || badgeLabel !== undefined) && (\n <Group\n align=\"center\"\n gap=\"xs\"\n wrap=\"wrap\"\n style={{ gridArea: \"title\", minWidth: 0, overflowWrap: \"anywhere\" }}\n >\n {title !== undefined && (\n <Text\n fw={500}\n size=\"md\"\n c={titleColor()}\n style={{ lineHeight: 1.35, minWidth: 0, overflowWrap: \"anywhere\" }}\n >\n {title}\n </Text>\n )}\n {badgeLabel !== undefined && (\n <Badge color={color} size=\"sm\" variant=\"light\">\n {badgeLabel}\n </Badge>\n )}\n </Group>\n )}\n\n {description !== undefined && (\n <Box style={{ gridArea: \"description\", minWidth: 0, overflowWrap: \"anywhere\" }}>\n <BannerDescription>{description}</BannerDescription>\n </Box>\n )}\n\n {resolvedActions.length > 0 && (\n <Box\n sx={{\n display: \"flex\",\n flexDirection: { base: \"column\", sm: \"row\" },\n alignItems: \"stretch\",\n justifyContent: \"flex-end\",\n gap: spacing.xs,\n minWidth: 0,\n width: { base: \"100%\", sm: \"max-content\" },\n maxWidth: \"100%\",\n }}\n style={{ gridArea: \"actions\", alignSelf: \"center\", justifySelf: \"end\" }}\n >\n {resolvedActions.map(({ label, size, ...buttonProps }, index) => (\n <Button\n key={buttonProps.id ?? (typeof label === \"string\" ? label : `banner-action-${index}`)}\n {...buttonProps}\n color={color}\n size={size ?? \"sm\"}\n variant={actionVariant(tone, index < resolvedActions.length - 1)}\n style={{\n ...buttonProps.style,\n boxSizing: \"border-box\",\n flex: \"0 1 auto\",\n maxWidth: \"100%\",\n overflowWrap: \"anywhere\",\n whiteSpace: \"normal\",\n width: \"100%\",\n }}\n >\n {label}\n </Button>\n ))}\n </Box>\n )}\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const index = require("../../../theme/index.cjs");
|
|
5
|
+
const layout = require("../../primitives/layout.cjs");
|
|
6
|
+
const Popover = require("../../primitives/Popover/Popover.cjs");
|
|
7
|
+
const Text = require("../../../node_modules/@mantine/core/esm/components/Text/Text.cjs");
|
|
8
|
+
const ScrollArea = require("../../../node_modules/@mantine/core/esm/components/ScrollArea/ScrollArea.cjs");
|
|
9
|
+
const DEFAULT_EMPTY_MESSAGE = "There are no tasks to do right now. You'll see a badge on this icon when there are.";
|
|
10
|
+
function TaskInboxPopover({
|
|
11
|
+
children,
|
|
12
|
+
className,
|
|
13
|
+
count,
|
|
14
|
+
emptyMessage = DEFAULT_EMPTY_MESSAGE,
|
|
15
|
+
onClose,
|
|
16
|
+
opened,
|
|
17
|
+
target,
|
|
18
|
+
title = "Tasks",
|
|
19
|
+
width = 420,
|
|
20
|
+
zIndex
|
|
21
|
+
}) {
|
|
22
|
+
const showEmpty = count === 0;
|
|
23
|
+
const responsiveWidth = `min(${width}px, calc(100vw - 32px))`;
|
|
24
|
+
return /* @__PURE__ */ jsxRuntime.jsx(layout.Box, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
25
|
+
Popover.Popover,
|
|
26
|
+
{
|
|
27
|
+
onChange: (next) => {
|
|
28
|
+
if (!next) onClose();
|
|
29
|
+
},
|
|
30
|
+
opened,
|
|
31
|
+
position: "bottom-start",
|
|
32
|
+
returnFocus: true,
|
|
33
|
+
trapFocus: true,
|
|
34
|
+
width: responsiveWidth,
|
|
35
|
+
withinPortal: true,
|
|
36
|
+
zIndex,
|
|
37
|
+
children: [
|
|
38
|
+
/* @__PURE__ */ jsxRuntime.jsx(Popover.Popover.Target, { children: target }),
|
|
39
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
40
|
+
Popover.Popover.Dropdown,
|
|
41
|
+
{
|
|
42
|
+
p: 0,
|
|
43
|
+
role: "dialog",
|
|
44
|
+
"aria-label": title,
|
|
45
|
+
style: { overflow: "hidden", maxWidth: "100%" },
|
|
46
|
+
children: [
|
|
47
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
48
|
+
layout.Box,
|
|
49
|
+
{
|
|
50
|
+
px: "md",
|
|
51
|
+
py: "sm",
|
|
52
|
+
style: { borderBottom: `1px solid ${index.fairmintVars.colorBorderDefault}` },
|
|
53
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(Text.Text, { fw: 600, size: "md", children: [
|
|
54
|
+
title,
|
|
55
|
+
count > 0 ? ` (${count})` : ""
|
|
56
|
+
] })
|
|
57
|
+
}
|
|
58
|
+
),
|
|
59
|
+
showEmpty ? /* @__PURE__ */ jsxRuntime.jsx(layout.Box, { px: "md", py: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(Text.Text, { size: "sm", children: emptyMessage }) }) : (
|
|
60
|
+
// Vertical-only hover scrollbar (no offset gutter): offsetScrollbars
|
|
61
|
+
// reserved a permanent right pad that looked like empty padding.
|
|
62
|
+
/* @__PURE__ */ jsxRuntime.jsx(ScrollArea.ScrollArea.Autosize, { mah: 360, scrollbars: "y", type: "hover", children: /* @__PURE__ */ jsxRuntime.jsx(layout.Box, { maw: "100%", style: { overflow: "hidden" }, children: /* @__PURE__ */ jsxRuntime.jsx(layout.Stack, { gap: 0, children }) }) })
|
|
63
|
+
)
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
) });
|
|
70
|
+
}
|
|
71
|
+
exports.TaskInboxPopover = TaskInboxPopover;
|
|
72
|
+
//# sourceMappingURL=TaskInboxPopover.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskInboxPopover.cjs","sources":["../../../../src/components/generic/TaskInboxPopover/TaskInboxPopover.tsx"],"sourcesContent":["import type { ReactElement, ReactNode } from \"react\";\nimport { fairmintVars } from \"../../../theme\";\nimport { Box, ScrollArea, Stack, Text } from \"../../primitives/layout\";\nimport { Popover } from \"../../primitives/Popover/Popover\";\n\nexport interface TaskInboxPopoverProps {\n /** Controlled open state. */\n opened: boolean;\n /** Called when the popover requests close. */\n onClose: () => void;\n /** Bell or trigger element wrapped by `Popover.Target`. */\n target: ReactElement;\n /**\n * Unresolved actionable task count (header + empty-state source of truth).\n * Parent must derive this from the same list passed as `children`.\n */\n count: number;\n /** Header title. @default \"Tasks\" */\n title?: string;\n /** Empty-state copy when `count` is 0. */\n emptyMessage?: ReactNode;\n /** Task list body — typically studiov2 `<Tasks />`. Ignored when `count` is 0. */\n children: ReactNode;\n /**\n * Preferred popover width in px. Clamped to the viewport so mobile does not\n * clip. @default 420\n */\n width?: number;\n /** Portal stacking order — Studio shell menus use `SHELL_MENU_Z_INDEX`. */\n zIndex?: number;\n className?: string;\n}\n\nconst DEFAULT_EMPTY_MESSAGE =\n \"There are no tasks to do right now. You'll see a badge on this icon when there are.\";\n\n/**\n * Studio bell task inbox shell — Mantine popover chrome around a `TaskRow` list.\n *\n * Domain mapping (task type → copy, link, priority) stays in the consuming app.\n * This component owns layout, header, scroll region, and empty state framing.\n */\nexport function TaskInboxPopover({\n children,\n className,\n count,\n emptyMessage = DEFAULT_EMPTY_MESSAGE,\n onClose,\n opened,\n target,\n title = \"Tasks\",\n width = 420,\n zIndex,\n}: TaskInboxPopoverProps) {\n const showEmpty = count === 0;\n const responsiveWidth = `min(${width}px, calc(100vw - 32px))`;\n\n return (\n <Box className={className}>\n <Popover\n onChange={(next) => {\n if (!next) onClose();\n }}\n opened={opened}\n position=\"bottom-start\"\n returnFocus\n trapFocus\n width={responsiveWidth}\n withinPortal\n zIndex={zIndex}\n >\n <Popover.Target>{target}</Popover.Target>\n <Popover.Dropdown\n p={0}\n role=\"dialog\"\n aria-label={title}\n style={{ overflow: \"hidden\", maxWidth: \"100%\" }}\n >\n <Box\n px=\"md\"\n py=\"sm\"\n style={{ borderBottom: `1px solid ${fairmintVars.colorBorderDefault}` }}\n >\n <Text fw={600} size=\"md\">\n {title}\n {count > 0 ? ` (${count})` : \"\"}\n </Text>\n </Box>\n {showEmpty ? (\n <Box px=\"md\" py=\"sm\">\n <Text size=\"sm\">{emptyMessage}</Text>\n </Box>\n ) : (\n // Vertical-only hover scrollbar (no offset gutter): offsetScrollbars\n // reserved a permanent right pad that looked like empty padding.\n <ScrollArea.Autosize mah={360} scrollbars=\"y\" type=\"hover\">\n <Box maw=\"100%\" style={{ overflow: \"hidden\" }}>\n <Stack gap={0}>{children}</Stack>\n </Box>\n </ScrollArea.Autosize>\n )}\n </Popover.Dropdown>\n </Popover>\n </Box>\n );\n}\n"],"names":["jsx","Box","jsxs","Popover","fairmintVars","Text","ScrollArea","Stack"],"mappings":";;;;;;;;AAiCA,MAAM,wBACJ;AAQK,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR;AACF,GAA0B;AACxB,QAAM,YAAY,UAAU;AAC5B,QAAM,kBAAkB,OAAO,KAAK;AAEpC,SACEA,2BAAAA,IAACC,OAAAA,OAAI,WACH,UAAAC,2BAAAA;AAAAA,IAACC,QAAAA;AAAAA,IAAA;AAAA,MACC,UAAU,CAAC,SAAS;AAClB,YAAI,CAAC,KAAM,SAAA;AAAA,MACb;AAAA,MACA;AAAA,MACA,UAAS;AAAA,MACT,aAAW;AAAA,MACX,WAAS;AAAA,MACT,OAAO;AAAA,MACP,cAAY;AAAA,MACZ;AAAA,MAEA,UAAA;AAAA,QAAAH,2BAAAA,IAACG,QAAAA,QAAQ,QAAR,EAAgB,UAAA,OAAA,CAAO;AAAA,QACxBD,2BAAAA;AAAAA,UAACC,QAAAA,QAAQ;AAAA,UAAR;AAAA,YACC,GAAG;AAAA,YACH,MAAK;AAAA,YACL,cAAY;AAAA,YACZ,OAAO,EAAE,UAAU,UAAU,UAAU,OAAA;AAAA,YAEvC,UAAA;AAAA,cAAAH,2BAAAA;AAAAA,gBAACC,OAAAA;AAAAA,gBAAA;AAAA,kBACC,IAAG;AAAA,kBACH,IAAG;AAAA,kBACH,OAAO,EAAE,cAAc,aAAaG,MAAAA,aAAa,kBAAkB,GAAA;AAAA,kBAEnE,UAAAF,2BAAAA,KAACG,KAAAA,MAAA,EAAK,IAAI,KAAK,MAAK,MACjB,UAAA;AAAA,oBAAA;AAAA,oBACA,QAAQ,IAAI,KAAK,KAAK,MAAM;AAAA,kBAAA,EAAA,CAC/B;AAAA,gBAAA;AAAA,cAAA;AAAA,cAED,YACCL,2BAAAA,IAACC,YAAA,EAAI,IAAG,MAAK,IAAG,MACd,UAAAD,2BAAAA,IAACK,KAAAA,MAAA,EAAK,MAAK,MAAM,UAAA,aAAA,CAAa,GAChC;AAAA;AAAA;AAAA,gBAIAL,2BAAAA,IAACM,WAAAA,WAAW,UAAX,EAAoB,KAAK,KAAK,YAAW,KAAI,MAAK,SACjD,UAAAN,2BAAAA,IAACC,OAAAA,KAAA,EAAI,KAAI,QAAO,OAAO,EAAE,UAAU,SAAA,GACjC,UAAAD,2BAAAA,IAACO,OAAAA,OAAA,EAAM,KAAK,GAAI,SAAA,CAAS,EAAA,CAC3B,EAAA,CACF;AAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAEJ;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ;;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ReactElement, ReactNode } from 'react';
|
|
2
|
+
export interface TaskInboxPopoverProps {
|
|
3
|
+
/** Controlled open state. */
|
|
4
|
+
opened: boolean;
|
|
5
|
+
/** Called when the popover requests close. */
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
/** Bell or trigger element wrapped by `Popover.Target`. */
|
|
8
|
+
target: ReactElement;
|
|
9
|
+
/**
|
|
10
|
+
* Unresolved actionable task count (header + empty-state source of truth).
|
|
11
|
+
* Parent must derive this from the same list passed as `children`.
|
|
12
|
+
*/
|
|
13
|
+
count: number;
|
|
14
|
+
/** Header title. @default "Tasks" */
|
|
15
|
+
title?: string;
|
|
16
|
+
/** Empty-state copy when `count` is 0. */
|
|
17
|
+
emptyMessage?: ReactNode;
|
|
18
|
+
/** Task list body — typically studiov2 `<Tasks />`. Ignored when `count` is 0. */
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
/**
|
|
21
|
+
* Preferred popover width in px. Clamped to the viewport so mobile does not
|
|
22
|
+
* clip. @default 420
|
|
23
|
+
*/
|
|
24
|
+
width?: number;
|
|
25
|
+
/** Portal stacking order — Studio shell menus use `SHELL_MENU_Z_INDEX`. */
|
|
26
|
+
zIndex?: number;
|
|
27
|
+
className?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Studio bell task inbox shell — Mantine popover chrome around a `TaskRow` list.
|
|
31
|
+
*
|
|
32
|
+
* Domain mapping (task type → copy, link, priority) stays in the consuming app.
|
|
33
|
+
* This component owns layout, header, scroll region, and empty state framing.
|
|
34
|
+
*/
|
|
35
|
+
export declare function TaskInboxPopover({ children, className, count, emptyMessage, onClose, opened, target, title, width, zIndex, }: TaskInboxPopoverProps): import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
//# sourceMappingURL=TaskInboxPopover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskInboxPopover.d.ts","sourceRoot":"","sources":["../../../../src/components/generic/TaskInboxPopover/TaskInboxPopover.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKrD,MAAM,WAAW,qBAAqB;IACpC,6BAA6B;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,2DAA2D;IAC3D,MAAM,EAAE,YAAY,CAAC;IACrB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,kFAAkF;IAClF,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAKD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,SAAS,EACT,KAAK,EACL,YAAoC,EACpC,OAAO,EACP,MAAM,EACN,MAAM,EACN,KAAe,EACf,KAAW,EACX,MAAM,GACP,EAAE,qBAAqB,2CAoDvB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { fairmintVars } from "../../../theme/index.js";
|
|
3
|
+
import { Box, Stack } from "../../primitives/layout.js";
|
|
4
|
+
import { Popover } from "../../primitives/Popover/Popover.js";
|
|
5
|
+
import { Text } from "../../../node_modules/@mantine/core/esm/components/Text/Text.js";
|
|
6
|
+
import { ScrollArea } from "../../../node_modules/@mantine/core/esm/components/ScrollArea/ScrollArea.js";
|
|
7
|
+
const DEFAULT_EMPTY_MESSAGE = "There are no tasks to do right now. You'll see a badge on this icon when there are.";
|
|
8
|
+
function TaskInboxPopover({
|
|
9
|
+
children,
|
|
10
|
+
className,
|
|
11
|
+
count,
|
|
12
|
+
emptyMessage = DEFAULT_EMPTY_MESSAGE,
|
|
13
|
+
onClose,
|
|
14
|
+
opened,
|
|
15
|
+
target,
|
|
16
|
+
title = "Tasks",
|
|
17
|
+
width = 420,
|
|
18
|
+
zIndex
|
|
19
|
+
}) {
|
|
20
|
+
const showEmpty = count === 0;
|
|
21
|
+
const responsiveWidth = `min(${width}px, calc(100vw - 32px))`;
|
|
22
|
+
return /* @__PURE__ */ jsx(Box, { className, children: /* @__PURE__ */ jsxs(
|
|
23
|
+
Popover,
|
|
24
|
+
{
|
|
25
|
+
onChange: (next) => {
|
|
26
|
+
if (!next) onClose();
|
|
27
|
+
},
|
|
28
|
+
opened,
|
|
29
|
+
position: "bottom-start",
|
|
30
|
+
returnFocus: true,
|
|
31
|
+
trapFocus: true,
|
|
32
|
+
width: responsiveWidth,
|
|
33
|
+
withinPortal: true,
|
|
34
|
+
zIndex,
|
|
35
|
+
children: [
|
|
36
|
+
/* @__PURE__ */ jsx(Popover.Target, { children: target }),
|
|
37
|
+
/* @__PURE__ */ jsxs(
|
|
38
|
+
Popover.Dropdown,
|
|
39
|
+
{
|
|
40
|
+
p: 0,
|
|
41
|
+
role: "dialog",
|
|
42
|
+
"aria-label": title,
|
|
43
|
+
style: { overflow: "hidden", maxWidth: "100%" },
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ jsx(
|
|
46
|
+
Box,
|
|
47
|
+
{
|
|
48
|
+
px: "md",
|
|
49
|
+
py: "sm",
|
|
50
|
+
style: { borderBottom: `1px solid ${fairmintVars.colorBorderDefault}` },
|
|
51
|
+
children: /* @__PURE__ */ jsxs(Text, { fw: 600, size: "md", children: [
|
|
52
|
+
title,
|
|
53
|
+
count > 0 ? ` (${count})` : ""
|
|
54
|
+
] })
|
|
55
|
+
}
|
|
56
|
+
),
|
|
57
|
+
showEmpty ? /* @__PURE__ */ jsx(Box, { px: "md", py: "sm", children: /* @__PURE__ */ jsx(Text, { size: "sm", children: emptyMessage }) }) : (
|
|
58
|
+
// Vertical-only hover scrollbar (no offset gutter): offsetScrollbars
|
|
59
|
+
// reserved a permanent right pad that looked like empty padding.
|
|
60
|
+
/* @__PURE__ */ jsx(ScrollArea.Autosize, { mah: 360, scrollbars: "y", type: "hover", children: /* @__PURE__ */ jsx(Box, { maw: "100%", style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx(Stack, { gap: 0, children }) }) })
|
|
61
|
+
)
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
) });
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
TaskInboxPopover
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=TaskInboxPopover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskInboxPopover.js","sources":["../../../../src/components/generic/TaskInboxPopover/TaskInboxPopover.tsx"],"sourcesContent":["import type { ReactElement, ReactNode } from \"react\";\nimport { fairmintVars } from \"../../../theme\";\nimport { Box, ScrollArea, Stack, Text } from \"../../primitives/layout\";\nimport { Popover } from \"../../primitives/Popover/Popover\";\n\nexport interface TaskInboxPopoverProps {\n /** Controlled open state. */\n opened: boolean;\n /** Called when the popover requests close. */\n onClose: () => void;\n /** Bell or trigger element wrapped by `Popover.Target`. */\n target: ReactElement;\n /**\n * Unresolved actionable task count (header + empty-state source of truth).\n * Parent must derive this from the same list passed as `children`.\n */\n count: number;\n /** Header title. @default \"Tasks\" */\n title?: string;\n /** Empty-state copy when `count` is 0. */\n emptyMessage?: ReactNode;\n /** Task list body — typically studiov2 `<Tasks />`. Ignored when `count` is 0. */\n children: ReactNode;\n /**\n * Preferred popover width in px. Clamped to the viewport so mobile does not\n * clip. @default 420\n */\n width?: number;\n /** Portal stacking order — Studio shell menus use `SHELL_MENU_Z_INDEX`. */\n zIndex?: number;\n className?: string;\n}\n\nconst DEFAULT_EMPTY_MESSAGE =\n \"There are no tasks to do right now. You'll see a badge on this icon when there are.\";\n\n/**\n * Studio bell task inbox shell — Mantine popover chrome around a `TaskRow` list.\n *\n * Domain mapping (task type → copy, link, priority) stays in the consuming app.\n * This component owns layout, header, scroll region, and empty state framing.\n */\nexport function TaskInboxPopover({\n children,\n className,\n count,\n emptyMessage = DEFAULT_EMPTY_MESSAGE,\n onClose,\n opened,\n target,\n title = \"Tasks\",\n width = 420,\n zIndex,\n}: TaskInboxPopoverProps) {\n const showEmpty = count === 0;\n const responsiveWidth = `min(${width}px, calc(100vw - 32px))`;\n\n return (\n <Box className={className}>\n <Popover\n onChange={(next) => {\n if (!next) onClose();\n }}\n opened={opened}\n position=\"bottom-start\"\n returnFocus\n trapFocus\n width={responsiveWidth}\n withinPortal\n zIndex={zIndex}\n >\n <Popover.Target>{target}</Popover.Target>\n <Popover.Dropdown\n p={0}\n role=\"dialog\"\n aria-label={title}\n style={{ overflow: \"hidden\", maxWidth: \"100%\" }}\n >\n <Box\n px=\"md\"\n py=\"sm\"\n style={{ borderBottom: `1px solid ${fairmintVars.colorBorderDefault}` }}\n >\n <Text fw={600} size=\"md\">\n {title}\n {count > 0 ? ` (${count})` : \"\"}\n </Text>\n </Box>\n {showEmpty ? (\n <Box px=\"md\" py=\"sm\">\n <Text size=\"sm\">{emptyMessage}</Text>\n </Box>\n ) : (\n // Vertical-only hover scrollbar (no offset gutter): offsetScrollbars\n // reserved a permanent right pad that looked like empty padding.\n <ScrollArea.Autosize mah={360} scrollbars=\"y\" type=\"hover\">\n <Box maw=\"100%\" style={{ overflow: \"hidden\" }}>\n <Stack gap={0}>{children}</Stack>\n </Box>\n </ScrollArea.Autosize>\n )}\n </Popover.Dropdown>\n </Popover>\n </Box>\n );\n}\n"],"names":[],"mappings":";;;;;;AAiCA,MAAM,wBACJ;AAQK,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR;AACF,GAA0B;AACxB,QAAM,YAAY,UAAU;AAC5B,QAAM,kBAAkB,OAAO,KAAK;AAEpC,SACE,oBAAC,OAAI,WACH,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,UAAU,CAAC,SAAS;AAClB,YAAI,CAAC,KAAM,SAAA;AAAA,MACb;AAAA,MACA;AAAA,MACA,UAAS;AAAA,MACT,aAAW;AAAA,MACX,WAAS;AAAA,MACT,OAAO;AAAA,MACP,cAAY;AAAA,MACZ;AAAA,MAEA,UAAA;AAAA,QAAA,oBAAC,QAAQ,QAAR,EAAgB,UAAA,OAAA,CAAO;AAAA,QACxB;AAAA,UAAC,QAAQ;AAAA,UAAR;AAAA,YACC,GAAG;AAAA,YACH,MAAK;AAAA,YACL,cAAY;AAAA,YACZ,OAAO,EAAE,UAAU,UAAU,UAAU,OAAA;AAAA,YAEvC,UAAA;AAAA,cAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,IAAG;AAAA,kBACH,IAAG;AAAA,kBACH,OAAO,EAAE,cAAc,aAAa,aAAa,kBAAkB,GAAA;AAAA,kBAEnE,UAAA,qBAAC,MAAA,EAAK,IAAI,KAAK,MAAK,MACjB,UAAA;AAAA,oBAAA;AAAA,oBACA,QAAQ,IAAI,KAAK,KAAK,MAAM;AAAA,kBAAA,EAAA,CAC/B;AAAA,gBAAA;AAAA,cAAA;AAAA,cAED,YACC,oBAAC,KAAA,EAAI,IAAG,MAAK,IAAG,MACd,UAAA,oBAAC,MAAA,EAAK,MAAK,MAAM,UAAA,aAAA,CAAa,GAChC;AAAA;AAAA;AAAA,gBAIA,oBAAC,WAAW,UAAX,EAAoB,KAAK,KAAK,YAAW,KAAI,MAAK,SACjD,UAAA,oBAAC,KAAA,EAAI,KAAI,QAAO,OAAO,EAAE,UAAU,SAAA,GACjC,UAAA,oBAAC,OAAA,EAAM,KAAK,GAAI,SAAA,CAAS,EAAA,CAC3B,EAAA,CACF;AAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAEJ;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ;"}
|
|
@@ -75,14 +75,17 @@ function TaskRow({
|
|
|
75
75
|
py: 10,
|
|
76
76
|
w: "100%",
|
|
77
77
|
miw: 0,
|
|
78
|
+
maw: "100%",
|
|
78
79
|
style: {
|
|
79
80
|
background: isCritical ? CRITICAL_ROW_BACKGROUND : index.fairmintVars.colorBgSurface,
|
|
80
81
|
border: isList ? "none" : `1px solid ${index.fairmintVars.colorBorderDefault}`,
|
|
81
82
|
borderBottom: isList && withDivider ? `1px solid ${index.fairmintVars.colorBorderDefault}` : void 0,
|
|
82
|
-
borderRadius: isList ? 0 : 10
|
|
83
|
+
borderRadius: isList ? 0 : 10,
|
|
84
|
+
overflow: "hidden",
|
|
85
|
+
boxSizing: "border-box"
|
|
83
86
|
},
|
|
84
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { align: "center", gap: "sm", justify: "space-between", wrap: "nowrap", children: [
|
|
85
|
-
/* @__PURE__ */ jsxRuntime.jsxs(layout.Stack, { gap: 4, miw: 0, style: { flex: 1 }, children: [
|
|
87
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { align: "center", gap: "sm", justify: "space-between", wrap: "nowrap", miw: 0, w: "100%", children: [
|
|
88
|
+
/* @__PURE__ */ jsxRuntime.jsxs(layout.Stack, { gap: 4, miw: 0, style: { flex: "1 1 auto", overflow: "hidden" }, children: [
|
|
86
89
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
87
90
|
Text.Text,
|
|
88
91
|
{
|
|
@@ -105,7 +108,7 @@ function TaskRow({
|
|
|
105
108
|
lineClamp: 2,
|
|
106
109
|
size: "sm",
|
|
107
110
|
c: index.fairmintVars.colorTextPrimary,
|
|
108
|
-
style: { minWidth: 0 },
|
|
111
|
+
style: { minWidth: 0, overflowWrap: "anywhere" },
|
|
109
112
|
children: title
|
|
110
113
|
}
|
|
111
114
|
),
|
|
@@ -115,7 +118,7 @@ function TaskRow({
|
|
|
115
118
|
c: index.fairmintVars.colorTextSecondary,
|
|
116
119
|
lineClamp: 2,
|
|
117
120
|
size: "sm",
|
|
118
|
-
style: { minWidth: 0 },
|
|
121
|
+
style: { minWidth: 0, overflowWrap: "anywhere" },
|
|
119
122
|
children: description
|
|
120
123
|
}
|
|
121
124
|
) : null
|
|
@@ -128,6 +131,19 @@ function TaskRow({
|
|
|
128
131
|
color: colors.colors.primary,
|
|
129
132
|
size: "sm",
|
|
130
133
|
variant: isCritical ? "filled" : "light",
|
|
134
|
+
styles: {
|
|
135
|
+
root: {
|
|
136
|
+
// Keep CTA + dismiss inside the 420px inbox without x-scroll.
|
|
137
|
+
maxWidth: 148,
|
|
138
|
+
minWidth: 0,
|
|
139
|
+
overflow: "hidden"
|
|
140
|
+
},
|
|
141
|
+
label: {
|
|
142
|
+
overflow: "hidden",
|
|
143
|
+
textOverflow: "ellipsis",
|
|
144
|
+
whiteSpace: "nowrap"
|
|
145
|
+
}
|
|
146
|
+
},
|
|
131
147
|
children: actionLabel
|
|
132
148
|
}
|
|
133
149
|
),
|
|
@@ -136,8 +152,17 @@ function TaskRow({
|
|
|
136
152
|
{
|
|
137
153
|
"aria-label": dismissLabel,
|
|
138
154
|
color: colors.colors.neutral,
|
|
139
|
-
onClick:
|
|
155
|
+
onClick: (event) => {
|
|
156
|
+
event.preventDefault();
|
|
157
|
+
event.stopPropagation();
|
|
158
|
+
onDismiss();
|
|
159
|
+
},
|
|
160
|
+
onMouseDown: (event) => {
|
|
161
|
+
event.preventDefault();
|
|
162
|
+
event.stopPropagation();
|
|
163
|
+
},
|
|
140
164
|
size: "md",
|
|
165
|
+
style: { flexShrink: 0 },
|
|
141
166
|
variant: "subtle",
|
|
142
167
|
children: /* @__PURE__ */ jsxRuntime.jsx(DefaultDismissIcon, {})
|
|
143
168
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskRow.cjs","sources":["../../../../src/components/generic/TaskRow/TaskRow.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { fairmintVars } from \"../../../theme\";\nimport { colors } from \"../../../theme/colors\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Button, type ButtonProps } from \"../../primitives/Button/Button\";\nimport { Box, Group, Stack, Text } from \"../../primitives/layout\";\n\nexport type TaskRowPriority = \"critical\" | \"high\" | \"medium\" | \"low\";\n\nexport type TaskRowVariant = \"standalone\" | \"list\";\n\nexport interface TaskRowActionProps\n extends Omit<ButtonProps, \"children\" | \"color\" | \"variant\" | \"size\"> {\n /** Visible primary CTA label. */\n label: ReactNode;\n}\n\nexport interface TaskRowProps {\n /** Priority / urgency affordance. @default \"medium\" */\n priority?: TaskRowPriority;\n /**\n * Severity label shown above the title in uppercase plain text.\n * Defaults to the capitalized priority name (for example, \"Critical\", \"High\").\n */\n priorityLabel?: string;\n /** Task title. */\n title: string;\n /** Supporting description. */\n description: string;\n /**\n * Caller-formatted due date or age (for example, \"Due today\", \"3 days ago\").\n * Included in the accessible name when provided; not shown beside the CTA.\n */\n timingLabel?: string;\n /** Primary workflow CTA. */\n action: TaskRowActionProps;\n /**\n * Layout presentation. Use `list` inside a shared bordered stack so rows\n * sit flush with no card gaps. @default \"standalone\"\n */\n variant?: TaskRowVariant;\n /**\n * When `variant=\"list\"`, draw a bottom divider. Set false on the last row.\n * @default true\n */\n withDivider?: boolean;\n /** Optional dismiss or snooze handler. */\n onDismiss?: () => void;\n /** Accessible label for the dismiss control. @default \"Dismiss task\" */\n dismissLabel?: string;\n /** Accessible label for the row. Defaults to title plus timing when provided. */\n ariaLabel?: string;\n className?: string;\n}\n\nconst PRIORITY_SEVERITY_COLORS = {\n critical: fairmintVars.colorErrorText,\n // Mid warning ramp (amber) — clearer than warning-text/solid brown vs error red.\n high: \"warning.5\",\n medium: \"warning.5\",\n low: fairmintVars.colorTextTertiary,\n} as const;\n\nconst DEFAULT_PRIORITY_LABELS: Record<TaskRowPriority, string> = {\n critical: \"Critical\",\n high: \"High\",\n medium: \"Medium\",\n low: \"Low\",\n};\n\n/** Soft critical tint that stays readable in Light and Dark (avoids solid error-bg in dark). */\nconst CRITICAL_ROW_BACKGROUND = `color-mix(in srgb, ${fairmintVars.colorErrorSolid} 18%, ${fairmintVars.colorBgSurface})`;\n\nfunction DefaultDismissIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/**\n * Presentational durable-task row for Studio Tasks and future Investor inbox work.\n *\n * Owns uppercase severity text above the title, description, a right-pinned\n * vertically centered `sm` primary CTA, and optional dismiss. Only `critical`\n * priority receives a semantic fill; non-critical rows stay on the neutral\n * list surface. The owning workflow resolves completion; this row does not\n * infer resolution from dismiss.\n */\nexport function TaskRow({\n action,\n ariaLabel,\n className,\n description,\n dismissLabel = \"Dismiss task\",\n onDismiss,\n priority = \"medium\",\n priorityLabel,\n timingLabel,\n title,\n variant = \"standalone\",\n withDivider = true,\n}: TaskRowProps) {\n const resolvedSeverityLabel = priorityLabel ?? DEFAULT_PRIORITY_LABELS[priority];\n const resolvedAriaLabel =\n ariaLabel ??\n (timingLabel\n ? `${title}. ${resolvedSeverityLabel} priority. ${timingLabel}`\n : `${title}. ${resolvedSeverityLabel} priority`);\n const isCritical = priority === \"critical\";\n const isList = variant === \"list\";\n const hasDescription = description.trim().length > 0;\n const { label: actionLabel, ...actionProps } = action;\n\n return (\n <Box\n aria-label={resolvedAriaLabel}\n role=\"group\"\n className={className}\n data-priority={priority}\n data-testid=\"task-row\"\n data-variant={variant}\n px=\"sm\"\n py={10}\n w=\"100%\"\n miw={0}\n style={{\n background: isCritical ? CRITICAL_ROW_BACKGROUND : fairmintVars.colorBgSurface,\n border: isList ? \"none\" : `1px solid ${fairmintVars.colorBorderDefault}`,\n borderBottom:\n isList && withDivider ? `1px solid ${fairmintVars.colorBorderDefault}` : undefined,\n borderRadius: isList ? 0 : 10,\n }}\n >\n <Group align=\"center\" gap=\"sm\" justify=\"space-between\" wrap=\"nowrap\">\n <Stack gap={4} miw={0} style={{ flex: 1 }}>\n <Text\n aria-hidden\n c={PRIORITY_SEVERITY_COLORS[priority]}\n fw={650}\n size=\"xs\"\n style={{\n letterSpacing: \"0.03em\",\n lineHeight: 1.2,\n textTransform: \"uppercase\",\n }}\n >\n {resolvedSeverityLabel}\n </Text>\n\n <Text\n fw={600}\n lineClamp={2}\n size=\"sm\"\n c={fairmintVars.colorTextPrimary}\n style={{ minWidth: 0 }}\n >\n {title}\n </Text>\n\n {hasDescription ? (\n <Text\n c={fairmintVars.colorTextSecondary}\n lineClamp={2}\n size=\"sm\"\n style={{ minWidth: 0 }}\n >\n {description}\n </Text>\n ) : null}\n </Stack>\n\n <Group align=\"center\" gap=\"xs\" wrap=\"nowrap\" style={{ flexShrink: 0 }}>\n <Button\n {...actionProps}\n color={colors.primary}\n size=\"sm\"\n variant={isCritical ? \"filled\" : \"light\"}\n >\n {actionLabel}\n </Button>\n {onDismiss ? (\n <ActionIcon\n aria-label={dismissLabel}\n color={colors.neutral}\n onClick={onDismiss}\n size=\"md\"\n variant=\"subtle\"\n >\n <DefaultDismissIcon />\n </ActionIcon>\n ) : null}\n </Group>\n </Group>\n </Box>\n );\n}\n"],"names":["fairmintVars","jsxs","jsx","Box","Group","Stack","Text","Button","colors","ActionIcon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TaskRow.cjs","sources":["../../../../src/components/generic/TaskRow/TaskRow.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { fairmintVars } from \"../../../theme\";\nimport { colors } from \"../../../theme/colors\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Button, type ButtonProps } from \"../../primitives/Button/Button\";\nimport { Box, Group, Stack, Text } from \"../../primitives/layout\";\n\nexport type TaskRowPriority = \"critical\" | \"high\" | \"medium\" | \"low\";\n\nexport type TaskRowVariant = \"standalone\" | \"list\";\n\nexport interface TaskRowActionProps\n extends Omit<ButtonProps, \"children\" | \"color\" | \"variant\" | \"size\"> {\n /** Visible primary CTA label. */\n label: ReactNode;\n}\n\nexport interface TaskRowProps {\n /** Priority / urgency affordance. @default \"medium\" */\n priority?: TaskRowPriority;\n /**\n * Severity label shown above the title in uppercase plain text.\n * Defaults to the capitalized priority name (for example, \"Critical\", \"High\").\n */\n priorityLabel?: string;\n /** Task title. */\n title: string;\n /** Supporting description. */\n description: string;\n /**\n * Caller-formatted due date or age (for example, \"Due today\", \"3 days ago\").\n * Included in the accessible name when provided; not shown beside the CTA.\n */\n timingLabel?: string;\n /** Primary workflow CTA. */\n action: TaskRowActionProps;\n /**\n * Layout presentation. Use `list` inside a shared bordered stack so rows\n * sit flush with no card gaps. @default \"standalone\"\n */\n variant?: TaskRowVariant;\n /**\n * When `variant=\"list\"`, draw a bottom divider. Set false on the last row.\n * @default true\n */\n withDivider?: boolean;\n /** Optional dismiss or snooze handler. */\n onDismiss?: () => void;\n /** Accessible label for the dismiss control. @default \"Dismiss task\" */\n dismissLabel?: string;\n /** Accessible label for the row. Defaults to title plus timing when provided. */\n ariaLabel?: string;\n className?: string;\n}\n\nconst PRIORITY_SEVERITY_COLORS = {\n critical: fairmintVars.colorErrorText,\n // Mid warning ramp (amber) — clearer than warning-text/solid brown vs error red.\n high: \"warning.5\",\n medium: \"warning.5\",\n low: fairmintVars.colorTextTertiary,\n} as const;\n\nconst DEFAULT_PRIORITY_LABELS: Record<TaskRowPriority, string> = {\n critical: \"Critical\",\n high: \"High\",\n medium: \"Medium\",\n low: \"Low\",\n};\n\n/** Soft critical tint that stays readable in Light and Dark (avoids solid error-bg in dark). */\nconst CRITICAL_ROW_BACKGROUND = `color-mix(in srgb, ${fairmintVars.colorErrorSolid} 18%, ${fairmintVars.colorBgSurface})`;\n\nfunction DefaultDismissIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/**\n * Presentational durable-task row for Studio Tasks and future Investor inbox work.\n *\n * Owns uppercase severity text above the title, description, a right-pinned\n * vertically centered `sm` primary CTA, and optional dismiss. Only `critical`\n * priority receives a semantic fill; non-critical rows stay on the neutral\n * list surface. The owning workflow resolves completion; this row does not\n * infer resolution from dismiss.\n */\nexport function TaskRow({\n action,\n ariaLabel,\n className,\n description,\n dismissLabel = \"Dismiss task\",\n onDismiss,\n priority = \"medium\",\n priorityLabel,\n timingLabel,\n title,\n variant = \"standalone\",\n withDivider = true,\n}: TaskRowProps) {\n const resolvedSeverityLabel = priorityLabel ?? DEFAULT_PRIORITY_LABELS[priority];\n const resolvedAriaLabel =\n ariaLabel ??\n (timingLabel\n ? `${title}. ${resolvedSeverityLabel} priority. ${timingLabel}`\n : `${title}. ${resolvedSeverityLabel} priority`);\n const isCritical = priority === \"critical\";\n const isList = variant === \"list\";\n const hasDescription = description.trim().length > 0;\n const { label: actionLabel, ...actionProps } = action;\n\n return (\n <Box\n aria-label={resolvedAriaLabel}\n role=\"group\"\n className={className}\n data-priority={priority}\n data-testid=\"task-row\"\n data-variant={variant}\n px=\"sm\"\n py={10}\n w=\"100%\"\n miw={0}\n maw=\"100%\"\n style={{\n background: isCritical ? CRITICAL_ROW_BACKGROUND : fairmintVars.colorBgSurface,\n border: isList ? \"none\" : `1px solid ${fairmintVars.colorBorderDefault}`,\n borderBottom:\n isList && withDivider ? `1px solid ${fairmintVars.colorBorderDefault}` : undefined,\n borderRadius: isList ? 0 : 10,\n overflow: \"hidden\",\n boxSizing: \"border-box\",\n }}\n >\n <Group align=\"center\" gap=\"sm\" justify=\"space-between\" wrap=\"nowrap\" miw={0} w=\"100%\">\n <Stack gap={4} miw={0} style={{ flex: \"1 1 auto\", overflow: \"hidden\" }}>\n <Text\n aria-hidden\n c={PRIORITY_SEVERITY_COLORS[priority]}\n fw={650}\n size=\"xs\"\n style={{\n letterSpacing: \"0.03em\",\n lineHeight: 1.2,\n textTransform: \"uppercase\",\n }}\n >\n {resolvedSeverityLabel}\n </Text>\n\n <Text\n fw={600}\n lineClamp={2}\n size=\"sm\"\n c={fairmintVars.colorTextPrimary}\n style={{ minWidth: 0, overflowWrap: \"anywhere\" }}\n >\n {title}\n </Text>\n\n {hasDescription ? (\n <Text\n c={fairmintVars.colorTextSecondary}\n lineClamp={2}\n size=\"sm\"\n style={{ minWidth: 0, overflowWrap: \"anywhere\" }}\n >\n {description}\n </Text>\n ) : null}\n </Stack>\n\n <Group align=\"center\" gap=\"xs\" wrap=\"nowrap\" style={{ flexShrink: 0 }}>\n <Button\n {...actionProps}\n color={colors.primary}\n size=\"sm\"\n variant={isCritical ? \"filled\" : \"light\"}\n styles={{\n root: {\n // Keep CTA + dismiss inside the 420px inbox without x-scroll.\n maxWidth: 148,\n minWidth: 0,\n overflow: \"hidden\",\n },\n label: {\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n },\n }}\n >\n {actionLabel}\n </Button>\n {onDismiss ? (\n <ActionIcon\n aria-label={dismissLabel}\n color={colors.neutral}\n onClick={(event) => {\n // Keep the owning popover/dropdown open and make sure the\n // dismiss handler always receives the click (scroll overlays /\n // focus transfers can otherwise swallow it).\n event.preventDefault();\n event.stopPropagation();\n onDismiss();\n }}\n onMouseDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n size=\"md\"\n style={{ flexShrink: 0 }}\n variant=\"subtle\"\n >\n <DefaultDismissIcon />\n </ActionIcon>\n ) : null}\n </Group>\n </Group>\n </Box>\n );\n}\n"],"names":["fairmintVars","jsxs","jsx","Box","Group","Stack","Text","Button","colors","ActionIcon"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskRow.d.ts","sourceRoot":"","sources":["../../../../src/components/generic/TaskRow/TaskRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAG1E,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAErE,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,kBACf,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACpE,iCAAiC;IACjC,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,MAAM,EAAE,kBAAkB,CAAC;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAuCD;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,EACtB,MAAM,EACN,SAAS,EACT,SAAS,EACT,WAAW,EACX,YAA6B,EAC7B,SAAS,EACT,QAAmB,EACnB,aAAa,EACb,WAAW,EACX,KAAK,EACL,OAAsB,EACtB,WAAkB,GACnB,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"TaskRow.d.ts","sourceRoot":"","sources":["../../../../src/components/generic/TaskRow/TaskRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAG1E,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAErE,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,kBACf,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACpE,iCAAiC;IACjC,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,MAAM,EAAE,kBAAkB,CAAC;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAuCD;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,EACtB,MAAM,EACN,SAAS,EACT,SAAS,EACT,WAAW,EACX,YAA6B,EAC7B,SAAS,EACT,QAAmB,EACnB,aAAa,EACb,WAAW,EACX,KAAK,EACL,OAAsB,EACtB,WAAkB,GACnB,EAAE,YAAY,2CA0Hd"}
|
|
@@ -73,14 +73,17 @@ function TaskRow({
|
|
|
73
73
|
py: 10,
|
|
74
74
|
w: "100%",
|
|
75
75
|
miw: 0,
|
|
76
|
+
maw: "100%",
|
|
76
77
|
style: {
|
|
77
78
|
background: isCritical ? CRITICAL_ROW_BACKGROUND : fairmintVars.colorBgSurface,
|
|
78
79
|
border: isList ? "none" : `1px solid ${fairmintVars.colorBorderDefault}`,
|
|
79
80
|
borderBottom: isList && withDivider ? `1px solid ${fairmintVars.colorBorderDefault}` : void 0,
|
|
80
|
-
borderRadius: isList ? 0 : 10
|
|
81
|
+
borderRadius: isList ? 0 : 10,
|
|
82
|
+
overflow: "hidden",
|
|
83
|
+
boxSizing: "border-box"
|
|
81
84
|
},
|
|
82
|
-
children: /* @__PURE__ */ jsxs(Group, { align: "center", gap: "sm", justify: "space-between", wrap: "nowrap", children: [
|
|
83
|
-
/* @__PURE__ */ jsxs(Stack, { gap: 4, miw: 0, style: { flex: 1 }, children: [
|
|
85
|
+
children: /* @__PURE__ */ jsxs(Group, { align: "center", gap: "sm", justify: "space-between", wrap: "nowrap", miw: 0, w: "100%", children: [
|
|
86
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 4, miw: 0, style: { flex: "1 1 auto", overflow: "hidden" }, children: [
|
|
84
87
|
/* @__PURE__ */ jsx(
|
|
85
88
|
Text,
|
|
86
89
|
{
|
|
@@ -103,7 +106,7 @@ function TaskRow({
|
|
|
103
106
|
lineClamp: 2,
|
|
104
107
|
size: "sm",
|
|
105
108
|
c: fairmintVars.colorTextPrimary,
|
|
106
|
-
style: { minWidth: 0 },
|
|
109
|
+
style: { minWidth: 0, overflowWrap: "anywhere" },
|
|
107
110
|
children: title
|
|
108
111
|
}
|
|
109
112
|
),
|
|
@@ -113,7 +116,7 @@ function TaskRow({
|
|
|
113
116
|
c: fairmintVars.colorTextSecondary,
|
|
114
117
|
lineClamp: 2,
|
|
115
118
|
size: "sm",
|
|
116
|
-
style: { minWidth: 0 },
|
|
119
|
+
style: { minWidth: 0, overflowWrap: "anywhere" },
|
|
117
120
|
children: description
|
|
118
121
|
}
|
|
119
122
|
) : null
|
|
@@ -126,6 +129,19 @@ function TaskRow({
|
|
|
126
129
|
color: colors.primary,
|
|
127
130
|
size: "sm",
|
|
128
131
|
variant: isCritical ? "filled" : "light",
|
|
132
|
+
styles: {
|
|
133
|
+
root: {
|
|
134
|
+
// Keep CTA + dismiss inside the 420px inbox without x-scroll.
|
|
135
|
+
maxWidth: 148,
|
|
136
|
+
minWidth: 0,
|
|
137
|
+
overflow: "hidden"
|
|
138
|
+
},
|
|
139
|
+
label: {
|
|
140
|
+
overflow: "hidden",
|
|
141
|
+
textOverflow: "ellipsis",
|
|
142
|
+
whiteSpace: "nowrap"
|
|
143
|
+
}
|
|
144
|
+
},
|
|
129
145
|
children: actionLabel
|
|
130
146
|
}
|
|
131
147
|
),
|
|
@@ -134,8 +150,17 @@ function TaskRow({
|
|
|
134
150
|
{
|
|
135
151
|
"aria-label": dismissLabel,
|
|
136
152
|
color: colors.neutral,
|
|
137
|
-
onClick:
|
|
153
|
+
onClick: (event) => {
|
|
154
|
+
event.preventDefault();
|
|
155
|
+
event.stopPropagation();
|
|
156
|
+
onDismiss();
|
|
157
|
+
},
|
|
158
|
+
onMouseDown: (event) => {
|
|
159
|
+
event.preventDefault();
|
|
160
|
+
event.stopPropagation();
|
|
161
|
+
},
|
|
138
162
|
size: "md",
|
|
163
|
+
style: { flexShrink: 0 },
|
|
139
164
|
variant: "subtle",
|
|
140
165
|
children: /* @__PURE__ */ jsx(DefaultDismissIcon, {})
|
|
141
166
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskRow.js","sources":["../../../../src/components/generic/TaskRow/TaskRow.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { fairmintVars } from \"../../../theme\";\nimport { colors } from \"../../../theme/colors\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Button, type ButtonProps } from \"../../primitives/Button/Button\";\nimport { Box, Group, Stack, Text } from \"../../primitives/layout\";\n\nexport type TaskRowPriority = \"critical\" | \"high\" | \"medium\" | \"low\";\n\nexport type TaskRowVariant = \"standalone\" | \"list\";\n\nexport interface TaskRowActionProps\n extends Omit<ButtonProps, \"children\" | \"color\" | \"variant\" | \"size\"> {\n /** Visible primary CTA label. */\n label: ReactNode;\n}\n\nexport interface TaskRowProps {\n /** Priority / urgency affordance. @default \"medium\" */\n priority?: TaskRowPriority;\n /**\n * Severity label shown above the title in uppercase plain text.\n * Defaults to the capitalized priority name (for example, \"Critical\", \"High\").\n */\n priorityLabel?: string;\n /** Task title. */\n title: string;\n /** Supporting description. */\n description: string;\n /**\n * Caller-formatted due date or age (for example, \"Due today\", \"3 days ago\").\n * Included in the accessible name when provided; not shown beside the CTA.\n */\n timingLabel?: string;\n /** Primary workflow CTA. */\n action: TaskRowActionProps;\n /**\n * Layout presentation. Use `list` inside a shared bordered stack so rows\n * sit flush with no card gaps. @default \"standalone\"\n */\n variant?: TaskRowVariant;\n /**\n * When `variant=\"list\"`, draw a bottom divider. Set false on the last row.\n * @default true\n */\n withDivider?: boolean;\n /** Optional dismiss or snooze handler. */\n onDismiss?: () => void;\n /** Accessible label for the dismiss control. @default \"Dismiss task\" */\n dismissLabel?: string;\n /** Accessible label for the row. Defaults to title plus timing when provided. */\n ariaLabel?: string;\n className?: string;\n}\n\nconst PRIORITY_SEVERITY_COLORS = {\n critical: fairmintVars.colorErrorText,\n // Mid warning ramp (amber) — clearer than warning-text/solid brown vs error red.\n high: \"warning.5\",\n medium: \"warning.5\",\n low: fairmintVars.colorTextTertiary,\n} as const;\n\nconst DEFAULT_PRIORITY_LABELS: Record<TaskRowPriority, string> = {\n critical: \"Critical\",\n high: \"High\",\n medium: \"Medium\",\n low: \"Low\",\n};\n\n/** Soft critical tint that stays readable in Light and Dark (avoids solid error-bg in dark). */\nconst CRITICAL_ROW_BACKGROUND = `color-mix(in srgb, ${fairmintVars.colorErrorSolid} 18%, ${fairmintVars.colorBgSurface})`;\n\nfunction DefaultDismissIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/**\n * Presentational durable-task row for Studio Tasks and future Investor inbox work.\n *\n * Owns uppercase severity text above the title, description, a right-pinned\n * vertically centered `sm` primary CTA, and optional dismiss. Only `critical`\n * priority receives a semantic fill; non-critical rows stay on the neutral\n * list surface. The owning workflow resolves completion; this row does not\n * infer resolution from dismiss.\n */\nexport function TaskRow({\n action,\n ariaLabel,\n className,\n description,\n dismissLabel = \"Dismiss task\",\n onDismiss,\n priority = \"medium\",\n priorityLabel,\n timingLabel,\n title,\n variant = \"standalone\",\n withDivider = true,\n}: TaskRowProps) {\n const resolvedSeverityLabel = priorityLabel ?? DEFAULT_PRIORITY_LABELS[priority];\n const resolvedAriaLabel =\n ariaLabel ??\n (timingLabel\n ? `${title}. ${resolvedSeverityLabel} priority. ${timingLabel}`\n : `${title}. ${resolvedSeverityLabel} priority`);\n const isCritical = priority === \"critical\";\n const isList = variant === \"list\";\n const hasDescription = description.trim().length > 0;\n const { label: actionLabel, ...actionProps } = action;\n\n return (\n <Box\n aria-label={resolvedAriaLabel}\n role=\"group\"\n className={className}\n data-priority={priority}\n data-testid=\"task-row\"\n data-variant={variant}\n px=\"sm\"\n py={10}\n w=\"100%\"\n miw={0}\n style={{\n background: isCritical ? CRITICAL_ROW_BACKGROUND : fairmintVars.colorBgSurface,\n border: isList ? \"none\" : `1px solid ${fairmintVars.colorBorderDefault}`,\n borderBottom:\n isList && withDivider ? `1px solid ${fairmintVars.colorBorderDefault}` : undefined,\n borderRadius: isList ? 0 : 10,\n }}\n >\n <Group align=\"center\" gap=\"sm\" justify=\"space-between\" wrap=\"nowrap\">\n <Stack gap={4} miw={0} style={{ flex: 1 }}>\n <Text\n aria-hidden\n c={PRIORITY_SEVERITY_COLORS[priority]}\n fw={650}\n size=\"xs\"\n style={{\n letterSpacing: \"0.03em\",\n lineHeight: 1.2,\n textTransform: \"uppercase\",\n }}\n >\n {resolvedSeverityLabel}\n </Text>\n\n <Text\n fw={600}\n lineClamp={2}\n size=\"sm\"\n c={fairmintVars.colorTextPrimary}\n style={{ minWidth: 0 }}\n >\n {title}\n </Text>\n\n {hasDescription ? (\n <Text\n c={fairmintVars.colorTextSecondary}\n lineClamp={2}\n size=\"sm\"\n style={{ minWidth: 0 }}\n >\n {description}\n </Text>\n ) : null}\n </Stack>\n\n <Group align=\"center\" gap=\"xs\" wrap=\"nowrap\" style={{ flexShrink: 0 }}>\n <Button\n {...actionProps}\n color={colors.primary}\n size=\"sm\"\n variant={isCritical ? \"filled\" : \"light\"}\n >\n {actionLabel}\n </Button>\n {onDismiss ? (\n <ActionIcon\n aria-label={dismissLabel}\n color={colors.neutral}\n onClick={onDismiss}\n size=\"md\"\n variant=\"subtle\"\n >\n <DefaultDismissIcon />\n </ActionIcon>\n ) : null}\n </Group>\n </Group>\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TaskRow.js","sources":["../../../../src/components/generic/TaskRow/TaskRow.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { fairmintVars } from \"../../../theme\";\nimport { colors } from \"../../../theme/colors\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Button, type ButtonProps } from \"../../primitives/Button/Button\";\nimport { Box, Group, Stack, Text } from \"../../primitives/layout\";\n\nexport type TaskRowPriority = \"critical\" | \"high\" | \"medium\" | \"low\";\n\nexport type TaskRowVariant = \"standalone\" | \"list\";\n\nexport interface TaskRowActionProps\n extends Omit<ButtonProps, \"children\" | \"color\" | \"variant\" | \"size\"> {\n /** Visible primary CTA label. */\n label: ReactNode;\n}\n\nexport interface TaskRowProps {\n /** Priority / urgency affordance. @default \"medium\" */\n priority?: TaskRowPriority;\n /**\n * Severity label shown above the title in uppercase plain text.\n * Defaults to the capitalized priority name (for example, \"Critical\", \"High\").\n */\n priorityLabel?: string;\n /** Task title. */\n title: string;\n /** Supporting description. */\n description: string;\n /**\n * Caller-formatted due date or age (for example, \"Due today\", \"3 days ago\").\n * Included in the accessible name when provided; not shown beside the CTA.\n */\n timingLabel?: string;\n /** Primary workflow CTA. */\n action: TaskRowActionProps;\n /**\n * Layout presentation. Use `list` inside a shared bordered stack so rows\n * sit flush with no card gaps. @default \"standalone\"\n */\n variant?: TaskRowVariant;\n /**\n * When `variant=\"list\"`, draw a bottom divider. Set false on the last row.\n * @default true\n */\n withDivider?: boolean;\n /** Optional dismiss or snooze handler. */\n onDismiss?: () => void;\n /** Accessible label for the dismiss control. @default \"Dismiss task\" */\n dismissLabel?: string;\n /** Accessible label for the row. Defaults to title plus timing when provided. */\n ariaLabel?: string;\n className?: string;\n}\n\nconst PRIORITY_SEVERITY_COLORS = {\n critical: fairmintVars.colorErrorText,\n // Mid warning ramp (amber) — clearer than warning-text/solid brown vs error red.\n high: \"warning.5\",\n medium: \"warning.5\",\n low: fairmintVars.colorTextTertiary,\n} as const;\n\nconst DEFAULT_PRIORITY_LABELS: Record<TaskRowPriority, string> = {\n critical: \"Critical\",\n high: \"High\",\n medium: \"Medium\",\n low: \"Low\",\n};\n\n/** Soft critical tint that stays readable in Light and Dark (avoids solid error-bg in dark). */\nconst CRITICAL_ROW_BACKGROUND = `color-mix(in srgb, ${fairmintVars.colorErrorSolid} 18%, ${fairmintVars.colorBgSurface})`;\n\nfunction DefaultDismissIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/**\n * Presentational durable-task row for Studio Tasks and future Investor inbox work.\n *\n * Owns uppercase severity text above the title, description, a right-pinned\n * vertically centered `sm` primary CTA, and optional dismiss. Only `critical`\n * priority receives a semantic fill; non-critical rows stay on the neutral\n * list surface. The owning workflow resolves completion; this row does not\n * infer resolution from dismiss.\n */\nexport function TaskRow({\n action,\n ariaLabel,\n className,\n description,\n dismissLabel = \"Dismiss task\",\n onDismiss,\n priority = \"medium\",\n priorityLabel,\n timingLabel,\n title,\n variant = \"standalone\",\n withDivider = true,\n}: TaskRowProps) {\n const resolvedSeverityLabel = priorityLabel ?? DEFAULT_PRIORITY_LABELS[priority];\n const resolvedAriaLabel =\n ariaLabel ??\n (timingLabel\n ? `${title}. ${resolvedSeverityLabel} priority. ${timingLabel}`\n : `${title}. ${resolvedSeverityLabel} priority`);\n const isCritical = priority === \"critical\";\n const isList = variant === \"list\";\n const hasDescription = description.trim().length > 0;\n const { label: actionLabel, ...actionProps } = action;\n\n return (\n <Box\n aria-label={resolvedAriaLabel}\n role=\"group\"\n className={className}\n data-priority={priority}\n data-testid=\"task-row\"\n data-variant={variant}\n px=\"sm\"\n py={10}\n w=\"100%\"\n miw={0}\n maw=\"100%\"\n style={{\n background: isCritical ? CRITICAL_ROW_BACKGROUND : fairmintVars.colorBgSurface,\n border: isList ? \"none\" : `1px solid ${fairmintVars.colorBorderDefault}`,\n borderBottom:\n isList && withDivider ? `1px solid ${fairmintVars.colorBorderDefault}` : undefined,\n borderRadius: isList ? 0 : 10,\n overflow: \"hidden\",\n boxSizing: \"border-box\",\n }}\n >\n <Group align=\"center\" gap=\"sm\" justify=\"space-between\" wrap=\"nowrap\" miw={0} w=\"100%\">\n <Stack gap={4} miw={0} style={{ flex: \"1 1 auto\", overflow: \"hidden\" }}>\n <Text\n aria-hidden\n c={PRIORITY_SEVERITY_COLORS[priority]}\n fw={650}\n size=\"xs\"\n style={{\n letterSpacing: \"0.03em\",\n lineHeight: 1.2,\n textTransform: \"uppercase\",\n }}\n >\n {resolvedSeverityLabel}\n </Text>\n\n <Text\n fw={600}\n lineClamp={2}\n size=\"sm\"\n c={fairmintVars.colorTextPrimary}\n style={{ minWidth: 0, overflowWrap: \"anywhere\" }}\n >\n {title}\n </Text>\n\n {hasDescription ? (\n <Text\n c={fairmintVars.colorTextSecondary}\n lineClamp={2}\n size=\"sm\"\n style={{ minWidth: 0, overflowWrap: \"anywhere\" }}\n >\n {description}\n </Text>\n ) : null}\n </Stack>\n\n <Group align=\"center\" gap=\"xs\" wrap=\"nowrap\" style={{ flexShrink: 0 }}>\n <Button\n {...actionProps}\n color={colors.primary}\n size=\"sm\"\n variant={isCritical ? \"filled\" : \"light\"}\n styles={{\n root: {\n // Keep CTA + dismiss inside the 420px inbox without x-scroll.\n maxWidth: 148,\n minWidth: 0,\n overflow: \"hidden\",\n },\n label: {\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n },\n }}\n >\n {actionLabel}\n </Button>\n {onDismiss ? (\n <ActionIcon\n aria-label={dismissLabel}\n color={colors.neutral}\n onClick={(event) => {\n // Keep the owning popover/dropdown open and make sure the\n // dismiss handler always receives the click (scroll overlays /\n // focus transfers can otherwise swallow it).\n event.preventDefault();\n event.stopPropagation();\n onDismiss();\n }}\n onMouseDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n size=\"md\"\n style={{ flexShrink: 0 }}\n variant=\"subtle\"\n >\n <DefaultDismissIcon />\n </ActionIcon>\n ) : null}\n </Group>\n </Group>\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const Popover$1 = require("../../../node_modules/@mantine/core/esm/components/Popover/Popover.cjs");
|
|
5
|
+
function PopoverBase(props) {
|
|
6
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Popover$1.Popover, { shadow: "md", ...props });
|
|
7
|
+
}
|
|
8
|
+
const Popover = Object.assign(PopoverBase, {
|
|
9
|
+
Target: Popover$1.Popover.Target,
|
|
10
|
+
Dropdown: Popover$1.Popover.Dropdown
|
|
11
|
+
});
|
|
12
|
+
exports.Popover = Popover;
|
|
13
|
+
//# sourceMappingURL=Popover.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Popover.cjs","sources":["../../../../src/components/primitives/Popover/Popover.tsx"],"sourcesContent":["import { Popover as MantinePopover, type PopoverProps as MantinePopoverProps } from \"@mantine/core\";\n\nexport interface PopoverProps extends MantinePopoverProps {}\n\nfunction PopoverBase(props: PopoverProps) {\n return <MantinePopover shadow=\"md\" {...props} />;\n}\n\nexport const Popover = Object.assign(PopoverBase, {\n Target: MantinePopover.Target,\n Dropdown: MantinePopover.Dropdown,\n});\n"],"names":["jsx","MantinePopover"],"mappings":";;;;AAIA,SAAS,YAAY,OAAqB;AACxC,SAAOA,2BAAAA,IAACC,UAAAA,SAAA,EAAe,QAAO,MAAM,GAAG,OAAO;AAChD;AAEO,MAAM,UAAU,OAAO,OAAO,aAAa;AAAA,EAChD,QAAQA,UAAAA,QAAe;AAAA,EACvB,UAAUA,UAAAA,QAAe;AAC3B,CAAC;;"}
|