Skip to content

feat(box): DLT-3315 new DtBox primitive component#1203

Merged
Francis Rupert (francisrupert) merged 35 commits intonextfrom
dt-box
Apr 17, 2026
Merged

feat(box): DLT-3315 new DtBox primitive component#1203
Francis Rupert (francisrupert) merged 35 commits intonextfrom
dt-box

Conversation

@francisrupert
Copy link
Copy Markdown
Contributor

@francisrupert Francis Rupert (francisrupert) commented Apr 16, 2026

tumblr_n06sqsvDjt1soxxtxo4_250

🛠️ Type Of Change

  • Feature

📖 Jira Ticket

DLT-3315

📖 Description

New DtBox component — low-level surface/spacing primitive. Token-constrained props for padding, surface, border (color, width, radius), shadow, sizing, overflow, and scrollbar. Completes the primitive triad: DtBox (surface) + DtText (typography) + DtStack (layout).

Props across three tiers:

  1. core (9)
  2. directional padding/border-width (13)
  3. sizing (6).

All values validated against Dialtone token scales. CSS architecture uses @property registrations, parametric Less mixin. OKLCH relative color syntax supports d-bgo*/d-bco* opacity utilities.

Note

Yes, I'm breaking our soft "no LESS mixins rule", but this feels appropriate to do.

Scrollbar prop integrates v-dt-scrollbar directive with automatic inner viewport wrapper.

What it does NOT do

  • No flex layout (use DtStack for that)
  • no typography (use DtText for that),
  • no flex child, no margin, no positioning, etc. (Use CSS Utilities for those).

📦 Cross-Package Impact

Package Changes
dialtone-css box.lessProperty, base class, ~350 modifier classes
dialtone-vue DtBox component, constants, validators, tests (385), stories
dialtone-documentation Component page, sidebar entry, blog post, stack.md dogfooding migration
combinator Variants file, prop ordering in PROP_PRIORITY

💡 Context

Building a card surface previously required composing 5-7 CSS utility classes (d-bgc-*, d-bc-*, d-baw-*, d-bar-*, d-p-*, d-bs-*). DtBox replaces this with discoverable, validated props mapped to design tokens.

Benefits:

  • better DX
  • improved AI/LLM discoverability via MCP, and reduced hallucinations
  • reduced CSS utility composition errors and outright reducing CSS Utilities.
  • reinforces spacing vs. layout token distinction
  • sets the stage for a future Container Query strategy.
  • sets the stage for a future Elevation strategy.

📝 Checklist

For all PRs:

  • I have ensured no private Dialpad links or info are in the code or pull request description (Dialtone is a public repo!).
  • I have reviewed my changes.
  • I have added all relevant documentation.
  • I have considered the performance impact of my change.

For all Vue changes:

  • I have added / updated unit tests.
  • I have validated components with a screen reader.
  • I have validated components keyboard navigation.

For all CSS changes:

  • I have used design tokens whenever possible.
  • I have considered how this change will behave on different screen sizes.
  • I have visually validated my change in light and dark mode.
  • I have used gap or flexbox properties for layout instead of margin whenever possible.

If new component:

  • I am exporting any new components or constants:
    • from the index.js in the component directory.
    • from the index.js in the root (packages/dialtone-vue).
  • I have added the styles for the new component to the packages/dialtone-css package.
  • I have created a page for the new component on the documentation site in apps/dialtone-documentation.
  • I have added the new component to common/components_list.js
  • I have created a component story in storybook
  • I have created story / stories for any relevant component variants in storybook
  • I have created a docs page for the component in storybook.
  • I have checked that changing all props/slots via the UI in storybook works as expected.

🔮 Next Steps

  • Elevation system (composite prop composing surface + border + shadow)
  • Container query support via opt-in container prop
  • Explore baking DtBox into existing components (DtCard, DtNotice) as internal primitive
  • Doc site migration: convert remaining CSS utility patterns to DtBox across component pages
  • Migration scripts for low-hanging fruit.

📷 Screenshots / GIFs

box-playground.mp4
box-doc.mp4

Adds DtBox, a low-level surface/spacing primitive exposing token-validated props for padding, surface, borders, shadow, sizing, overflow, and scrollbar. Includes ~350 CSS modifier classes, Vue component with validators, tests, stories, docs, documentation updates, combinator/variants integration, and public exports.

@github-actions
Copy link
Copy Markdown
Contributor

Please add either the visual-test-ready or no-visual-test label to this PR depending on whether you want to run visual tests or not.
It is recommended to run visual tests if your PR changes any UI. ‼️

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 16, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a new DtBox UI primitive across code, styles, stories, tests, combinator variants, and documentation; updates site navigation and component registry. Introduces Vue component, constants, validators, Less styles, Storybook stories/variants, tests, docs, and combinator control ordering.

Changes

Cohort / File(s) Summary
Vue component core
packages/dialtone-vue/components/box/box.vue, packages/dialtone-vue/components/box/box_constants.js, packages/dialtone-vue/components/box/validators.js, packages/dialtone-vue/components/box/index.js, packages/dialtone-vue/index.js
New DtBox component (many props) with constants and validators; package re-export added to public API.
Styles
packages/dialtone-css/lib/build/less/components/box.less, packages/dialtone-css/lib/build/less/dialtone.less
New Less module adding .d-box, scrollbar wrapper, CSS custom properties, and numerous modifier classes (padding, surface, border, radius, shadow, sizing, overflow); imported into Dialtone build.
Stories & variants UI
packages/dialtone-vue/components/box/box.stories.js, packages/dialtone-vue/components/box/box_variants.story.vue, packages/combinator/src/variants/variants_box.js, packages/combinator/src/variants/variants.js
Storybook stories and a variants catalog for Box added; combinator variants file created and DtBox included in variants mapping.
Tests
packages/dialtone-vue/components/box/box.test.js
New Jest + Vue Test Utils suite covering rendering, polymorphic tag, modifier classes, scrollbar wrapper behavior, sizing/overflow, and attribute passthrough.
Combinator UI ordering
packages/combinator/src/components/option_bar/option_bar_member_group.vue
Extended PROP_PRIORITY to recognize box-related prop names (scrollbar, surface, border*, padding*, sizing, shadow, overflow), affecting generated control ordering.
Documentation & site
apps/dialtone-documentation/docs/components/box.md, apps/dialtone-documentation/docs/components/stack.md, apps/dialtone-documentation/docs/components/text.md, apps/dialtone-documentation/docs/dialtone/whats-new/posts/2026-4-22.md, apps/dialtone-documentation/docs/scratch.md, apps/dialtone-documentation/docs/_data/site-nav.json
Adds Box docs, demos, and a blog post; updates Stack examples to use DtBox, adds keywords to text.md, inserts Box into site nav, and updates scratch demos.
Registry
common/components_list.js
Registered box.vue in the common components list.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dt-box

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/dialtone-documentation/docs/dialtone/whats-new/posts/2026-4-22.md`:
- Line 74: Replace the non-canonical component links in the post: change the
relative "components/scrollbar.md" and the inconsistent "/components/box.md" to
the canonical component URL pattern used across the site (e.g., use the same
leading-slash and .html route format used elsewhere in the post such as
"/components/scrollbar.html" and "/components/box.html"), and ensure all
component links in this document follow that same canonical format.

In `@apps/dialtone-documentation/docs/scratch.md`:
- Line 1366: Replace deprecated surface token usage: update all DtBox instances
using surface="success-subtle" to the new token surface="positive-subtle" (e.g.,
the <dt-box padding="100" surface="success-subtle">Box demo</dt-box>
occurrences). Search for any other uses of surface="success-subtle" (including
the second occurrence noted) and change them to surface="positive-subtle" to
match the renamed tokens (no fallback aliases).

In `@packages/dialtone-vue/components/box/box.test.js`:
- Around line 177-196: Add tests that cover the new directional border-width
props on DtBox: mirror the existing borderWidth tests but assert that passing
borderWidthInline, borderWidthInlineStart, borderWidthInlineEnd,
borderWidthBlock, borderWidthBlockStart, and borderWidthBlockEnd produce the
corresponding CSS modifier classes (e.g. for value X expect classes like
d-box--bwi-X, d-box--bwi-start-X, d-box--bwi-end-X, d-box--bwb-X,
d-box--bwb-start-X, d-box--bwb-end-X), using DT_BOX_BORDER_WIDTH_VALUES and
mountComponent to iterate values (and filter out any sentinel like '100' as in
existing tests), and add negative tests that when each directional prop is
undefined no d-box--bwi* / d-box--bwb* classes are present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 5132be19-f1ad-4c67-9e9e-5d7f4f77e2f2

📥 Commits

Reviewing files that changed from the base of the PR and between 265e34c and bec9249.

📒 Files selected for processing (20)
  • apps/dialtone-documentation/docs/_data/site-nav.json
  • apps/dialtone-documentation/docs/components/box.md
  • apps/dialtone-documentation/docs/components/stack.md
  • apps/dialtone-documentation/docs/components/text.md
  • apps/dialtone-documentation/docs/dialtone/whats-new/posts/2026-4-22.md
  • apps/dialtone-documentation/docs/scratch.md
  • common/components_list.js
  • packages/combinator/src/components/option_bar/option_bar_member_group.vue
  • packages/combinator/src/variants/variants.js
  • packages/combinator/src/variants/variants_box.js
  • packages/dialtone-css/lib/build/less/components/box.less
  • packages/dialtone-css/lib/build/less/dialtone.less
  • packages/dialtone-vue/components/box/box.stories.js
  • packages/dialtone-vue/components/box/box.test.js
  • packages/dialtone-vue/components/box/box.vue
  • packages/dialtone-vue/components/box/box_constants.js
  • packages/dialtone-vue/components/box/box_variants.story.vue
  • packages/dialtone-vue/components/box/index.js
  • packages/dialtone-vue/components/box/validators.js
  • packages/dialtone-vue/index.js

Comment thread apps/dialtone-documentation/docs/scratch.md Outdated
Comment thread packages/dialtone-vue/components/box/box.test.js
@francisrupert Francis Rupert (francisrupert) added the no-visual-test Add this tag when the PR does not need visual testing label Apr 16, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
apps/dialtone-documentation/docs/scratch.md (1)

1366-1366: ⚠️ Potential issue | 🟡 Minor

Replace deprecated success-subtle DtBox surface token.

Line 1366 and Line 1534 still use surface="success-subtle". Please switch these to surface="positive-subtle" to match current token names and avoid invalid demo usage warnings.

Proposed fix
-  <dt-box padding="100" surface="success-subtle">Box demo</dt-box>
+  <dt-box padding="100" surface="positive-subtle">Box demo</dt-box>
...
-  <dt-box as="header" padding="200" surface="success-subtle" border-width="100">Box demo</dt-box>
+  <dt-box as="header" padding="200" surface="positive-subtle" border-width="100">Box demo</dt-box>

Based on learnings: In the dialtone repo (PR #1177), the broad rename from error/success/danger to critical/positive is intentional with no legacy aliases.

Also applies to: 1534-1534

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/dialtone-documentation/docs/scratch.md` at line 1366, Replace the
deprecated surface token value used on DtBox: find the DtBox usage(s) where
surface="success-subtle" (e.g., the dt-box demo instances) and change the
attribute value to surface="positive-subtle" so it uses the current token name
(ensure both occurrences are updated).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@apps/dialtone-documentation/docs/scratch.md`:
- Line 1366: Replace the deprecated surface token value used on DtBox: find the
DtBox usage(s) where surface="success-subtle" (e.g., the dt-box demo instances)
and change the attribute value to surface="positive-subtle" so it uses the
current token name (ensure both occurrences are updated).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 4852b3c6-102a-43e3-a43c-2537e0870567

📥 Commits

Reviewing files that changed from the base of the PR and between bec9249 and 4e41f9d.

📒 Files selected for processing (3)
  • apps/dialtone-documentation/docs/dialtone/whats-new/posts/2026-4-22.md
  • apps/dialtone-documentation/docs/scratch.md
  • packages/dialtone-vue/components/box/box.test.js
✅ Files skipped from review due to trivial changes (1)
  • apps/dialtone-documentation/docs/dialtone/whats-new/posts/2026-4-22.md

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 98e7612b4f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment thread packages/dialtone-vue/components/box/box.vue
Comment thread packages/dialtone-vue/components/box/box.vue
@francisrupert Francis Rupert (francisrupert) changed the title feat(box): DLT-3315 new primitive component feat(box): DLT-3315 new DtBox primitive component Apr 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

✔️ Deploy previews ready!
😎 Dialtone documentation preview: https://dialtone.dialpad.com/deploy-previews/pr-1203/
😎 Dialtone-vue preview: https://dialtone.dialpad.com/vue/deploy-previews/pr-1203/

Copy link
Copy Markdown
Contributor

@braddialpad Brad Paugh (braddialpad) left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really good. Just some success vs positive stuff.

Comment thread packages/dialtone-css/lib/build/less/components/box.less Outdated
Comment thread packages/dialtone-css/lib/build/less/components/box.less Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/dialtone-documentation/docs/scratch.md`:
- Line 1189: DtNotice currently uses a non-existent prop hide-action which is
ignored; change instances to use the exposed boolean prop showAction instead
(pass :show-action="false" where the intent is to hide the action). Locate the
DtNotice usages in the diff (e.g., the tag <dt-notice ...> around the reported
lines) and replace hide-action with :show-action="false" so the action is
actually hidden; apply the same change to the second occurrence mentioned.

In `@packages/dialtone-css/lib/build/less/components/box.less`:
- Around line 231-239: The scrollbar-content wrapper (.d-box__scrollbar-content)
fails to constrain when the parent only sets max-block-size because block-size:
100% cannot resolve; update the .d-box__scrollbar-content rule to add
max-block-size: inherit (in addition to block-size: 100%) so it inherits the
parent's max-block-size and allows the native-scroll fallback to activate;
adjust the declaration inside the .d-box__scrollbar-content block (which the
.d-box:has(> .d-box__scrollbar-content) selector relies on) accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 316e8383-382f-4877-a610-63af61a2cedc

📥 Commits

Reviewing files that changed from the base of the PR and between 6938503 and a1cbd37.

📒 Files selected for processing (2)
  • apps/dialtone-documentation/docs/scratch.md
  • packages/dialtone-css/lib/build/less/components/box.less

Comment thread apps/dialtone-documentation/docs/scratch.md
Comment thread packages/dialtone-css/lib/build/less/components/box.less
@francisrupert Francis Rupert (francisrupert) merged commit e0c942e into next Apr 17, 2026
13 checks passed
Brad Paugh (braddialpad) pushed a commit that referenced this pull request Apr 17, 2026
# [1.2.0-next.6](combinator/v1.2.0-next.5...combinator/v1.2.0-next.6) (2026-04-17)

### Features

* **Box:** DLT-3315 new DtBox primitive component ([#1203](#1203)) ([e0c942e](e0c942e))
* **Combinator:** DLT-3312 preview resolved value in sized props ([#1199](#1199)) ([61bb610](61bb610))
Brad Paugh (braddialpad) pushed a commit that referenced this pull request Apr 17, 2026
# [8.80.0-next.2](dialtone-css/v8.80.0-next.1...dialtone-css/v8.80.0-next.2) (2026-04-17)

### Features

* **Box:** DLT-3315 new DtBox primitive component ([#1203](#1203)) ([e0c942e](e0c942e))
Brad Paugh (braddialpad) pushed a commit that referenced this pull request Apr 17, 2026
# [3.220.0-next.2](dialtone-vue/v3.220.0-next.1...dialtone-vue/v3.220.0-next.2) (2026-04-17)

### Features

* **Box:** DLT-3315 new DtBox primitive component ([#1203](#1203)) ([e0c942e](e0c942e))
* **Combinator:** DLT-3312 preview resolved value in sized props ([#1199](#1199)) ([61bb610](61bb610))
Brad Paugh (braddialpad) pushed a commit that referenced this pull request Apr 17, 2026
# [9.180.0-next.2](dialtone/v9.180.0-next.1...dialtone/v9.180.0-next.2) (2026-04-17)

### Features

* **Box:** DLT-3315 new DtBox primitive component ([#1203](#1203)) ([e0c942e](e0c942e))
* **Combinator:** DLT-3312 preview resolved value in sized props ([#1199](#1199)) ([61bb610](61bb610))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-visual-test Add this tag when the PR does not need visual testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants