Skip to content

Commit

Permalink
Merge pull request #187 from US-CBP/feature/cbp-dropdown
Browse files Browse the repository at this point in the history
Misc Updates
  • Loading branch information
dgibson666 authored Aug 23, 2024
2 parents b1b0d0f + f1ae85e commit efbc267
Show file tree
Hide file tree
Showing 9 changed files with 3,627 additions and 4,179 deletions.
7,622 changes: 3,460 additions & 4,162 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"lerna": "^7.4.2",
"lerna": "^8.1.8",
"postcss-scss": "^4.0.9",
"prettier": "^2.8.8",
"stylelint": "^14.16.1",
Expand Down
7 changes: 4 additions & 3 deletions packages/web-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
"build-pages": "storybook build --output-dir storybook-static"
},
"dependencies": {
"@stencil/core": "^4.15.0"
"@stencil/core": "^4.15.0",
"lerna": "8.1.8"
},
"devDependencies": {
"@chromatic-com/storybook": "^1.5.0",
Expand All @@ -54,11 +55,11 @@
"@storybook/web-components-vite": "^8.1.6",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.11",
"@whitespace/storybook-addon-html": "^6.0.5",
"@whitespace/storybook-addon-html": "^6.1.1",
"jest": "^27.5.1",
"jest-cli": "^27.5.1",
"lit": "^3.1.2",
"puppeteer": "21.1.1",
"puppeteer": "^23.1.1",
"storybook": "^8.1.6",
"wc-storybook-helpers": "^2.0.1"
},
Expand Down
8 changes: 5 additions & 3 deletions packages/web-components/src/components/cbp-app/core.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@
//--cbp-responsive-spacing-outer: clamp( var(--cbp-space-5x), 0.179rem + 2.857vw, var(--cbp-space-11x));
--cbp-responsive-spacing-outer: var(--cbp-space-5x);
--cbp-responsive-spacing-inner: var(--cbp-responsive-spacing-outer); // temporary - for discussion

--cbp-responsive-spacing-gap: var(--cbp-space-4x);

}
@media (min-width: $cbp-breakpoint-md) {
:root {
--cbp-responsive-spacing-outer: var(--cbp-space-8x);
--cbp-responsive-spacing-gap: var(--cbp-space-7x);
}
}
@media (min-width: $cbp-breakpoint-xl) {
Expand Down Expand Up @@ -48,9 +52,7 @@ body {
}

p,
blockquote,
ul:not(ul ul):not(ul ol),
ol:not(ol ol):not(ol ul) {
blockquote {
margin-bottom: var(--cbp-space-4x);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ cbp-form-field-wrapper {
// All named slots within the shrinkwrap element are overlays
[slot] {
position: absolute;
inset-block-start: 0; // Needed for Firefox
display: inline-flex;
align-items: center;
height: 100%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,11 @@ cbp-form-field {
box-shadow: 0 0 0 1000px var(--cbp-form-field-color-bg) inset;
-webkit-text-fill-color: var(--cbp-form-field-color);
}

// Hide Edge's built-in password reveal control
::-ms-reveal {
display: none;
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ The Form Field component represents a generic, reusable pattern for form fields
* Additional notes on slotted form fields and their use, since these are not strictly controlled by the design system:
* Some input types, such as `email`, `tel`, and `url`, should not be used because they invoke browser-based validation, which is inconsistent across browsers and with the design system, and not always accessible.
* Use `inputmode` instead of HTML5 input types to provide a browser hint for the proper virtual keyboard on mobile devices without side effects noted above.
* The `select` with `multiple` (and `size`) attribute should not be used, as they have terrible usability. Use our `cbp-multiselect` (coming soon) instead.
* Input types such as `date`, `datetime` (deprecated), `datetime-local`, `month`, `week`, `time` may also vary by browser and not be styleable in accordance with the design system.
* While the `input type="number"` restricts non-numeric input on Chrome, this is not the case in Safari and Firefox. Implement validation appropriately with the knowledge that non-numeric characters may still be entered.
* The `select` with `multiple` (and `size`) attribute should not be used, as they have poor usability. Use our `cbp-multiselect` (coming soon) instead.
* Input types such as `date`, `datetime-local`, `month`, `week`, `time` may also vary by browser and not be fully customized in accordance with the design system.
* Some input types such as `month` and `week` are not supported in Safari and Firefox and should not be used.
* Use of the `size` attribute is discouraged as it does not represent a linear/consistent scale across input sizes and browsers.
* Furthermore, `size` is not valid on some input types such as `type="number"`.
* When necessary, it is recommended to use CSS to style the width of form fields (using a relative unit such as `ch` or `rem`) separate from their containers.
16 changes: 9 additions & 7 deletions packages/web-components/src/stories/byoi.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Thesis

We're testing the concept of Bring Your Own Input (BYOI) and Bring Your Own Button (BYOB). The core idea is that a generic wrapper component is created (`cbp-button` or `cbp-form input`), which can accept any sort of native HTML form input/control slotted within it rather than rendered by it.
We're testing the concept of Bring Your Own Input (BYOI). The core idea is that a generic wrapper component is created, `cbp-form-input`, which can accept any sort of native HTML form input/control slotted within it rather than rendered by it. This wrapper ties the label and description/error messages together to form a predictable, accessible input pattern.

The precedent has already been set in two regards:

Expand All @@ -21,14 +21,16 @@ Furthermore, this concept is inline with recent discussions of "HTML web compone

### Advantages

* Lessens the need to develop a web component or functional component duplicating every native form control.
* Web components duplicating form controls usually only implement a portion of the API because the number of attributes is HUGE and often conditional on other attributes (e.g., `input type="number"` adds more attributes like `min` and `max`, while making others such as `maxlength` invalid). This leaves it up to the consuming developer to improvise when the web component falls short of the native HTML spec, or forces the developer to add an extremely large number of properties to the component to duplicate each of the attributes (e.g., the `input` tag accepts 34 attributes *not counting* 40+ global HTML and ARIA attributes).
* Direct access to the interactive controls alleviates a common pain point working with web components. Frameworks like Angular, Vue, and HTMX want to place attributes/directives directly on the DOM elements, which is not easily done when those elements are rendered behind an asynchronously loaded web component that has its own internal rendering lifecycle.
* Native HTML elements automatically work with the web platform (e.g., native form post). This is often not the case with custom widgets/components.
* Slotting native HTML form controls lessens the need to develop and maintain dozens of web components and/or functional components duplicating every form control or input pattern.
* Web components duplicating form controls usually only implement a portion of the API because the number of attributes is HUGE and often conditional on other attributes (e.g., `input type="number"` adds more attributes like `min` and `max`, while making others such as `maxlength` invalid).
* This leaves it up to the consuming developer to improvise when the web component falls short of the native HTML spec, or forces the developer to add an extremely large number of properties to the component to duplicate each of the attributes (e.g., the `input` tag accepts 34 attributes *not counting* 40+ global HTML and ARIA attributes).
* Native HTML elements automatically work with the web platform (e.g., native form post and `FormData()`). This is often not the case with custom widgets/components.
* Native HTML elements handle user interactions and mobile transformations automatically, requiring significant effort to duplicated them within custom web components, if possible at all.

### Disadvantages

* Loose coupling with the inputs means more DOM manipulation instead of direct control inside of the component's reactive properties and rendering pipeline.
* Using native HTML elements means the consuming app may need to manipulate the native elements and attributes in some cases rather than reactive web component properties.


* DOM manipulation may present challenges with component reactivity.
* The amount of DOM manipulation seems minimal at this time, only affecting the form field `id` and `aria-` attributes that are dependent on component-specific generated `id`s.
* Using native HTML elements means the consuming app may need to manipulate the native elements and attributes in some cases rather than reactive web component properties.
139 changes: 138 additions & 1 deletion packages/web-components/src/stories/templates.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default {
},
},
args: {
username: 'John Smithington',
username: 'HASHIDX',
isLoggedIn: true,
},
};
Expand Down Expand Up @@ -125,6 +125,143 @@ const InternalTemplate = ({ isLoggedIn, username }) => {

export const Internal = InternalTemplate.bind({});


const Internal2ColumnTemplate = ({ isLoggedIn, username, contentGridSize, sidebarGridSize, gridBreakpoint }) => {
return `
<cbp-skip-nav></cbp-skip-nav>
<cbp-flex
direction="column"
sx='{"min-height":"100vh"}'
>
<header>
<cbp-universal-header
logo-src-lg="./assets/images/cbp-header-logo.svg"
logo-src-sm="./assets/images/cbp-seal.svg"
>
<ul>
${ isLoggedIn
? `
<li>
<cbp-button color="secondary" fill="ghost" context="dark-always">
<cbp-icon name="book"></cbp-icon>
<cbp-hide
hide-at="max-width: 64em"
sx='{"margin-left":"var(--cbp-space-2x)"}'
>App Directory</cbp-hide>
</cbp-button>
</li>
<li>
<cbp-button color="secondary" fill="ghost" context="dark-always">
<cbp-icon name="comment"></cbp-icon>
<cbp-hide
visually-hide-at="max-width: 64em"
sx='{"margin-left":"var(--cbp-space-2x)"}'
>Feedback</cbp-hide>
</cbp-button>
</li>
<li>
<cbp-button color="secondary" fill="ghost" context="dark-always">
<cbp-icon name="user"></cbp-icon>
<cbp-hide
visually-hide-at="max-width: 64em"
sx='{"margin-left":"var(--cbp-space-2x)"}'
>${username}</cbp-hide>
</cbp-button>
</li>
`
: `
<li>
<cbp-button tag="a" href="#" color="secondary" fill="ghost" context="dark-always">
<cbp-icon name="right-to-bracket" sx='{"margin-right":"var(--cbp-space-2x)"}'></cbp-icon>
Login
</cbp-button>
</li>
`
}
</ul>
</cbp-universal-header>
<cbp-app-header>
<a slot="cbp-home" href="/" class="nav-home">Application Name</a>
</cbp-app-header>
</header>
<cbp-grid
grid-template-columns="${contentGridSize} ${sidebarGridSize}"
gap="var(--cbp-space-7x)"
breakpoint="${gridBreakpoint}"
sx='{
"padding":"1rem var(--cbp-responsive-spacing-outer)",
"flex-grow":"2"
}'
>
<main id="main" tabindex="-1">
<cbp-typography tag="h1" divider="underline" sx='{"margin-bottom":"var(--cbp-space-5x)"}'>
Page Title
</cbp-typography>
<p>Main content here.</p>
</main>
<cbp-panel
aria-labelledby="panelheader"
role="complementary"
>
<cbp-typography
slot="cbp-panel-header"
tag="h3"
variant="heading-lg"
id="panelheader"
>
Sidebar Header
</cbp-typography>
<p>Sidebar Content</p>
</cbp-panel>
</cbp-grid>
<cbp-footer data-cbp-container-context="dark">
<nav slot="cbp-footer-nav">
<cbp-flex role="list" breakpoint="37.5rem">
<cbp-flex-item role="list-item">
<cbp-button tag="a" href="#" color="secondary" fill="ghost" context="dark-always">App Overview</cbp-button>
</cbp-flex-item>
<cbp-flex-item role="list-item">
<cbp-button tag="a" href="#" color="secondary" fill="ghost" context="dark-always">Trainings</cbp-button>
</cbp-flex-item>
<cbp-flex-item role="list-item">
<cbp-button tag="a" href="#" color="secondary" fill="ghost" context="dark-always">FAQs</cbp-button>
</cbp-flex-item>
<cbp-flex-item role="list-item">
<cbp-button tag="a" href="#" color="secondary" fill="ghost" context="dark-always">Release Notes</cbp-button>
</cbp-flex-item>
<cbp-flex role="list">
</nav>
<section>
<cbp-typography tag="h6" variant="heading-md" context="dark-always" sx='{"margin-bottom":"var(--cbp-space-2x)"}'>Application Support</cbp-typography>
<p><em>This application is maintained by The Office of Information Technology: <abbr title="Targeting and Analysis Systems Program Directorate">TASPD</abbr>.</em></p>
<cbp-flex gap="var(--cbp-space-4x)" wrap="wrap">
<span>Having an issue?</span>
<span>Email: <cbp-link href="mailto:somebody@example.com" context="dark-always">this-application-support@abc.def.gov</cbp-link></span>
<span>CBP Helpdesk: <cbp-link href="tel:555-555-5555" context="dark-always">(555) 555-5555</cbp-link></span>
</cbp-flex>
</section>
</cbp-footer>
</cbp-flex>
`;
};

export const Internal2Column = Internal2ColumnTemplate.bind({});
Internal2Column.args = {
contentGridSize: 'minmax(30rem, 3fr)',
sidebarGridSize: 'minmax(15rem, 1fr)',
gridBreakpoint: '50rem'
}




/*
const ExternalTemplate = () => {
return `
Expand Down

0 comments on commit efbc267

Please sign in to comment.