Standardize modal buttons and delete confirmations
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"id": "accent-contrast",
|
||||
"name": "NodeDcAccentContrast",
|
||||
"kind": "utility",
|
||||
"status": "draft-stable",
|
||||
"summary": "Shared contrast helper that derives readable text color from a component accent color.",
|
||||
"sourceRefs": [
|
||||
{
|
||||
"project": "nodedc_launcher",
|
||||
"file": "src/shared/lib/accentContrast.ts",
|
||||
"exports": [
|
||||
"getReadableNodedcTextRgb",
|
||||
"createNodedcAccentStyleVars",
|
||||
"getNodedcRelativeLuminance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "nodedc_taskmanager",
|
||||
"file": "plane-src/packages/utils/src/theme/nodedc-accent.ts",
|
||||
"exports": [
|
||||
"getReadableNodedcTextRgb",
|
||||
"applyNodedcAccent"
|
||||
]
|
||||
}
|
||||
],
|
||||
"visualContract": {
|
||||
"darkTextRgb": [11, 17, 23],
|
||||
"lightTextRgb": [245, 247, 251],
|
||||
"luminanceThreshold": 0.52,
|
||||
"cssVars": [
|
||||
"--nodedc-component-accent-rgb",
|
||||
"--nodedc-component-on-accent-rgb"
|
||||
]
|
||||
},
|
||||
"rules": [
|
||||
"Any filled accent button or active accent chip must use the computed on-accent text color.",
|
||||
"Do not hardcode black or white text on an accent fill unless the accent contrast helper owns that decision.",
|
||||
"Component-local accent variables are allowed when global --nodedc-accent-rgb is not the intended color for that component."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"id": "button",
|
||||
"name": "Button",
|
||||
"kind": "primitive",
|
||||
"status": "draft-stable",
|
||||
"summary": "Canonical text/action button used by launcher stages, admin editors, and modal footers.",
|
||||
"sourceRefs": [
|
||||
{
|
||||
"project": "nodedc_launcher",
|
||||
"file": "src/shared/ui/Button.tsx",
|
||||
"exports": ["Button"]
|
||||
},
|
||||
{
|
||||
"project": "nodedc_launcher",
|
||||
"file": "src/styles/globals.css",
|
||||
"classes": [
|
||||
"button",
|
||||
"button--primary",
|
||||
"button--secondary",
|
||||
"button--danger",
|
||||
"button--ghost",
|
||||
"button--accent",
|
||||
"button[data-surface='modal']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "nodedc_taskmanager",
|
||||
"file": "plane-src/apps/web/styles/globals.css",
|
||||
"classes": [
|
||||
"nodedc-modal-primary-button",
|
||||
"nodedc-modal-secondary-button",
|
||||
"nodedc-modal-danger-button"
|
||||
]
|
||||
}
|
||||
],
|
||||
"api": {
|
||||
"props": {
|
||||
"variant": ["primary", "secondary", "danger", "ghost", "accent"],
|
||||
"surface": ["default", "modal"],
|
||||
"accentRgb": "optional RGB tuple used by accent variant",
|
||||
"icon": "optional leading icon"
|
||||
}
|
||||
},
|
||||
"visualContract": {
|
||||
"height": "2.65rem default, tokens.size.modalButtonHeight on modal surface",
|
||||
"radius": "control",
|
||||
"fontWeight": "800",
|
||||
"outline": "never",
|
||||
"modalSecondaryDanger": "transparent until hover",
|
||||
"modalAccent": "filled component accent with computed on-accent text"
|
||||
},
|
||||
"rules": [
|
||||
"Use Button instead of hand-written button classes for text actions.",
|
||||
"Use IconButton or circle-action-button for icon-only actions.",
|
||||
"Inside modals, pass surface='modal' on every footer button.",
|
||||
"Modal Save and modal destructive confirm use variant='accent' with local accentRgb when the app accent differs.",
|
||||
"Inline modal delete buttons use variant='danger' with surface='modal'; they are transparent until neutral hover.",
|
||||
"Do not use red filled delete buttons outside NodeDcDeleteModal confirmation.",
|
||||
"Filled accent variants must use accent-contrast variables for readable text."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"id": "delete-modal",
|
||||
"name": "NodeDcDeleteModal",
|
||||
"kind": "component",
|
||||
"status": "draft-stable",
|
||||
"summary": "Canonical dark glass confirmation modal for destructive object deletion.",
|
||||
"sourceRefs": [
|
||||
{
|
||||
"project": "nodedc_launcher",
|
||||
"file": "src/shared/nodedc-ui/DeleteModal.tsx",
|
||||
"exports": ["NodeDcDeleteModal"]
|
||||
},
|
||||
{
|
||||
"project": "nodedc_launcher",
|
||||
"file": "src/styles/globals.css",
|
||||
"classes": [
|
||||
"nodedc-delete-modal-layer",
|
||||
"nodedc-delete-modal",
|
||||
"nodedc-delete-modal__icon",
|
||||
"nodedc-delete-modal__foot"
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "nodedc_taskmanager",
|
||||
"file": "plane-src/packages/ui/src/modals/alert-modal.tsx",
|
||||
"exports": ["AlertModalCore"]
|
||||
},
|
||||
{
|
||||
"project": "nodedc_taskmanager",
|
||||
"file": "plane-src/apps/web/styles/globals.css",
|
||||
"classes": [
|
||||
"nodedc-glass-modal",
|
||||
"nodedc-modal-alert-icon",
|
||||
"nodedc-modal-danger-button",
|
||||
"nodedc-modal-secondary-button"
|
||||
]
|
||||
}
|
||||
],
|
||||
"anatomy": [
|
||||
"fixed blurred overlay layer",
|
||||
"dark glass shell",
|
||||
"round alert icon",
|
||||
"title and description copy",
|
||||
"footer with secondary cancel and destructive confirm"
|
||||
],
|
||||
"visualContract": {
|
||||
"width": "min(34rem, viewport - 2.8rem)",
|
||||
"radius": "modal",
|
||||
"background": "transparent black detail glass, not monocolor fill",
|
||||
"blur": "44px detail glass pseudo-layer blur",
|
||||
"iconSize": "2.75rem circle",
|
||||
"iconColor": "component accent, white in launcher",
|
||||
"buttonHeight": "tokens.size.modalButtonHeight through Button surface='modal'",
|
||||
"buttonRadius": "control radius",
|
||||
"cancelButton": "Button variant='secondary' surface='modal'",
|
||||
"destructiveButton": "Button variant='accent' surface='modal' with computed on-accent text"
|
||||
},
|
||||
"rules": [
|
||||
"Use this component for every delete/destructive removal action.",
|
||||
"Never delete immediately from a row, footer, dropdown, or editor without this modal.",
|
||||
"Do not add visible outlines or hard stroke borders to the modal, icon, or buttons.",
|
||||
"The shell uses nodedc-glass-detail-surface so the panel blurs the actual content under it.",
|
||||
"The destructive button uses the shared Button accent variant and component-local accent contrast variables, not a hardcoded red fill.",
|
||||
"Cancel is secondary and stays left of the destructive confirm action.",
|
||||
"The description must name the object and describe dependent data that will also be removed."
|
||||
],
|
||||
"launcherBindings": [
|
||||
"service showcase deletion",
|
||||
"client/company deletion",
|
||||
"client membership removal",
|
||||
"client group deletion",
|
||||
"invite deletion"
|
||||
]
|
||||
}
|
||||
@@ -39,9 +39,11 @@
|
||||
},
|
||||
"rules": [
|
||||
"Delete is left of Save inside the right footer action group.",
|
||||
"Footer buttons use the shared Button primitive with surface='modal'.",
|
||||
"Inline delete buttons inside edit modals use Button variant='danger' surface='modal', stay transparent until hover, and do not use red danger fills.",
|
||||
"Save uses Button variant='accent' surface='modal' with local white launcher accent and computed on-accent text.",
|
||||
"Cancel stays on the left.",
|
||||
"Close action is circular and transparent until hover.",
|
||||
"Fields/selects/textareas share the same glass family."
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -12,25 +12,24 @@
|
||||
{
|
||||
"project": "nodedc_launcher",
|
||||
"file": "src/styles/globals.css",
|
||||
"classes": ["glass-surface", "admin-panel-nav", "admin-panel-content", "service-content-modal"]
|
||||
"classes": ["glass-surface", "glass-surface--detail", "nodedc-glass-detail-surface", "admin-panel-nav", "admin-panel-content", "service-content-modal"]
|
||||
},
|
||||
{
|
||||
"project": "nodedc_taskmanager",
|
||||
"file": "plane-src/apps/web/styles/globals.css",
|
||||
"classes": ["nodedc-dropdown-surface", "nodedc-modal-field", "nodedc-settings-card"]
|
||||
"classes": ["nodedc-work-item-property-button", "nodedc-settings-card", "nodedc-modal-field", "nodedc-dropdown-surface"]
|
||||
}
|
||||
],
|
||||
"tokens": {
|
||||
"radius": "card | modal | control depending on scale",
|
||||
"blur": "panel | modal | dropdown",
|
||||
"blur": "control | panel | modal | dropdown | detail",
|
||||
"background": "dark matte glass gradient over rgba black",
|
||||
"border": "none or transparent soft glass only"
|
||||
},
|
||||
"rules": [
|
||||
"Never use hard outline as the main visual boundary.",
|
||||
"Use background opacity and blur to separate layers.",
|
||||
"Use background opacity, pseudo-layer glass, and backdrop blur to separate layers.",
|
||||
"For major shells use radius.card or radius.modal.",
|
||||
"For controls inside shells use radius.control."
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user