Standardize NodeDC UI components

This commit is contained in:
DCCONSTRUCTIONS
2026-05-02 10:56:43 +03:00
parent c99c91c826
commit 69eb5260b0
22 changed files with 1955 additions and 550 deletions
+2 -3
View File
@@ -23,7 +23,7 @@
"tbody rows",
"inline editable cells",
"StatusControl cells",
"DateField cells",
"NodeDcDateField cells",
"CircleActionButton action cells"
],
"visualContract": {
@@ -36,8 +36,7 @@
"Create action is a solid circular plus, not a wide text CTA.",
"Inline editable cells use transparent input surfaces that brighten on hover/focus.",
"Status cells use StatusControl.",
"Date cells use CalendarPopover/DateField.",
"Date cells use CalendarPopover through NodeDcDateField.",
"Drag handles move full rows, not detached ghosts."
]
}
+12 -2
View File
@@ -7,7 +7,18 @@
"sourceRefs": [
{
"project": "nodedc_launcher",
"file": "src/widgets/top-bar/TopBar.tsx"
"file": "src/widgets/top-bar/TopBar.tsx",
"functions": ["TopBar"]
},
{
"project": "nodedc_launcher",
"file": "src/shared/nodedc-ui/Select.tsx",
"exports": ["NodeDcSelect"]
},
{
"project": "nodedc_launcher",
"file": "src/shared/nodedc-ui/ProfileMenu.tsx",
"exports": ["NodeDcProfileMenu"]
},
{
"project": "nodedc_launcher",
@@ -37,4 +48,3 @@
"Launcher and Task Manager headers must remain visually identical where routes overlap."
]
}
@@ -4,6 +4,12 @@
"kind": "component",
"status": "stable-reference",
"summary": "Date picker popover based on Task Manager DateDropdown and nodedc-calendar-shell styling.",
"implementation": {
"baseLibrary": "react-day-picker@9.5.0",
"localePackage": "date-fns@4.1.0",
"launcherComponent": "NodeDcDateField renders NodeDcDropdown + NodeDcCalendar; NodeDcCalendar delegates the month grid/range math to DayPicker instead of a hand-written grid.",
"isolation": "Calendar logic and styling live in src/shared/nodedc-ui/Calendar.tsx and src/shared/nodedc-ui/calendar.css. Feature screens must consume NodeDcDateField or NodeDcCalendar directly instead of creating local date wrappers."
},
"sourceRefs": [
{
"project": "nodedc_taskmanager",
@@ -15,10 +21,28 @@
"file": "plane-src/apps/web/styles/globals.css",
"classes": ["nodedc-calendar-shell"]
},
{
"project": "nodedc_launcher",
"file": "src/shared/nodedc-ui/Calendar.tsx",
"exports": [
"NodeDcDateField",
"NodeDcCalendar",
"NodeDcDateFieldProps",
"NodeDcCalendarProps",
"NodeDcCalendarRangePreview",
"NodeDcDateInput",
"NodeDcWeekStartsOn"
]
},
{
"project": "nodedc_launcher",
"file": "src/shared/nodedc-ui/calendar.css",
"classes": ["nodedc-ui-calendar", "nodedc-ui-calendar-frame", "nodedc-ui-date-trigger"]
},
{
"project": "nodedc_launcher",
"file": "src/widgets/admin-overlay/AdminOverlay.tsx",
"functions": ["DateField"]
"consumers": ["ClientsSection", "ClientEditorModal", "InvitesSection"]
}
],
"anatomy": [
@@ -33,15 +57,22 @@
"surface": "DropdownSurface",
"calendarRadius": "1.1rem",
"dayButtonRadius": "999px",
"selectedRangeFill": "accentRgb with high contrast dark text",
"selectedRangeFill": "continuous accent row fill under the day numbers; row breaks create rounded start/end caps",
"todayMarker": "today is always a circular ring marker; inside an accent range the ring uses the dark on-accent color and the day cell remains range-filled, not solid-filled",
"outsideDays": "muted"
},
"behaviorContract": [
"Default placement bottom-start.",
"Render through portal.",
"Support minDate, maxDate, clearable value, start-of-week preference.",
"Close on select when closeOnSelect is true."
"Support minDate, maxDate, clearable value, closeOnSelect, empty labels, popover width, and start-of-week preference.",
"Close on select when closeOnSelect is true.",
"When rangePreview or rangeStart/rangeEnd are present, render a continuous accent range preview while still selecting one field value.",
"When only one date is present, render a single circular selected date.",
"Today must not be solid-filled. It uses an inset circular ring both outside and inside a range; inside a range the row fill remains visible behind the ring."
],
"nextImplementationStep": "Replace launcher native input date fallback with this shared calendar component."
"currentConsumers": [
"Client demo/contract/paid dates",
"Invite expiration dates",
"Any future date field in admin modals and tables"
]
}
@@ -16,12 +16,13 @@
},
{
"project": "nodedc_launcher",
"file": "src/shared/ui/PortalDropdown.tsx"
"file": "src/shared/nodedc-ui/Dropdown.tsx",
"exports": ["NodeDcDropdown"]
},
{
"project": "nodedc_launcher",
"file": "src/styles/globals.css",
"classes": ["portal-dropdown", "nodedc-dropdown-surface"]
"classes": ["nodedc-ui-dropdown-surface", "nodedc-dropdown-surface", "nodedc-ui-option", "nodedc-ui-dropdown-search"]
}
],
"visualContract": {
@@ -35,7 +36,7 @@
"behaviorContract": [
"Render on fixed/portal layer when inside cards, sidebars, tables, sticky headers, or scroll containers.",
"Close on outside pointer and Escape.",
"Use Popper or equivalent fixed-position placement.",
"Use Popper or equivalent fixed-position placement based on trigger bounds.",
"Default selection placement is bottom-start.",
"Default action placement for card quick actions is bottom-start or bottom-end depending on anchor edge."
],
@@ -45,4 +46,3 @@
"outline": "none"
}
}
+12 -2
View File
@@ -14,6 +14,16 @@
"project": "nodedc_taskmanager",
"file": "plane-src/packages/ui/src/dropdowns/action-dropdown.tsx",
"exports": ["ActionDropdown"]
},
{
"project": "nodedc_launcher",
"file": "src/shared/nodedc-ui/ProfileMenu.tsx",
"exports": ["NodeDcProfileMenu"]
},
{
"project": "nodedc_launcher",
"file": "src/widgets/top-bar/TopBar.tsx",
"functions": ["TopBar profile trigger"]
}
],
"anatomy": [
@@ -35,7 +45,7 @@
"rules": [
"Profile popover is an ActionDropdown menuContent variant, not a separate dropdown engine.",
"Avatar trigger stays circular and borderless.",
"Menu uses DropdownSurface/ActionDropdown stacking rules."
"Menu uses DropdownSurface/ActionDropdown stacking rules.",
"Launcher implementation must keep the profile trigger pill visually identical to Task Manager header."
]
}
@@ -0,0 +1,51 @@
{
"id": "select-dropdown",
"name": "NodeDcSelect",
"kind": "component",
"status": "draft-stable",
"summary": "Shared select/dropdown control for statuses, roles, clients, profile switches, filters, and compact table cells.",
"sourceRefs": [
{
"project": "nodedc_launcher",
"file": "src/shared/nodedc-ui/Select.tsx",
"exports": ["NodeDcSelect", "NodeDcSelectOption"]
},
{
"project": "nodedc_launcher",
"file": "src/shared/nodedc-ui/Dropdown.tsx",
"exports": ["NodeDcDropdown"]
},
{
"project": "nodedc_taskmanager",
"file": "plane-src/packages/ui/src/dropdowns/action-dropdown.tsx",
"exports": ["ActionDropdown"]
}
],
"anatomy": [
"trigger button or custom trigger render",
"portal DropdownSurface",
"optional search row",
"option rows with optional icon, description, tone, and selected check"
],
"visualContract": {
"triggerRadius": "999px for table/header/status controls, 1rem inside entity forms",
"menuSurface": "DropdownSurface",
"optionRadius": "0.92rem",
"selectedFill": "white/10 or tone-specific transparent fill",
"outline": "none"
},
"behaviorContract": [
"Never use native select for NODE.DC runtime UI.",
"Render options through portal/fixed dropdown layer.",
"Close on option select, outside pointer, and Escape.",
"Support custom trigger render for header pills and side-nav client switcher."
],
"currentConsumers": [
"TopBar client switcher",
"TopBar profile-role switcher",
"AdminOverlay client switcher",
"AdminOverlay client type selects",
"AdminOverlay membership role selects",
"AdminOverlay invite role selects"
]
}