Skip to content

Commit

Permalink
feat: add new split-button component
Browse files Browse the repository at this point in the history
  • Loading branch information
DRiFTy17 committed Nov 10, 2023
1 parent 0a79372 commit e21deef
Show file tree
Hide file tree
Showing 27 changed files with 769 additions and 16 deletions.
4 changes: 2 additions & 2 deletions src/dev/pages/button/button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ h3 {
--_custom-button-background: var(--forge-theme-primary);

@include button.provide-theme((
height: 56px,
dense-height: 40px,
min-height: 56px,
dense-min-height: 40px,
focus-indicator-offset: 4px,
shadow: elevation.value(2),
hover-shadow: elevation.value(4),
Expand Down
21 changes: 21 additions & 0 deletions src/dev/pages/split-button/split-button.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<div>
<h3 class="forge-typography--heading2">Common</h3>
<forge-split-button>
<forge-button class="primary-action">Send</forge-button>
<forge-menu id="split-menu">
<forge-button popover-icon></forge-button>
</forge-menu>
</forge-split-button>
</div>

<div>
<h3 class="forge-typography--heading2">Multiple</h3>
<forge-split-button>
<forge-button class="primary-action">Button one</forge-button>
<forge-button class="primary-action">Button two</forge-button>
<forge-button class="primary-action">Button three</forge-button>
<forge-button class="primary-action">Button four</forge-button>
</forge-split-button>
</div>

<script type="module" src="split-button.ts"></script>
25 changes: 25 additions & 0 deletions src/dev/pages/split-button/split-button.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<%-
include('./src/partials/page.ejs', {
page: {
title: 'Split button',
includePath: './pages/split-button/split-button.ejs',
options: [
{
type: 'select',
label: 'Variant',
id: 'opt-variant',
defaultValue: 'text',
options: [
{ value: 'text', label: 'Text (default)' },
{ value: 'flat', label: 'Flat' },
{ value: 'raised', label: 'Raised' },
{ value: 'outlined', label: 'Outlined' }
]
},
{ type: 'switch', label: 'Disabled', id: 'opt-disabled' },
{ type: 'switch', label: 'Dense', id: 'opt-dense' },
{ type: 'switch', label: 'Pill', id: 'opt-pill' }
]
}
})
%>
5 changes: 5 additions & 0 deletions src/dev/pages/split-button/split-button.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
forge-split-button[variant]:not([variant=text]) {
.primary-action {
min-width: 100px;
}
}
42 changes: 42 additions & 0 deletions src/dev/pages/split-button/split-button.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import '$src/shared';
import '@tylertech/forge/split-button';
import { IconRegistry } from '@tylertech/forge/icon';
import type { ISplitButtonComponent, SplitButtonVariant } from '@tylertech/forge/split-button';
import type { ISelectComponent } from '@tylertech/forge/select';
import type { ISwitchComponent } from '@tylertech/forge/switch';
import type { IMenuComponent } from '@tylertech/forge/menu';
import { tylIconArrowDropDown, tylIconScheduleSend, tylIconDeleteOutline, tylIconBookmarkBorder } from '@tylertech/tyler-icons/standard';
import './split-button.scss';

IconRegistry.define([tylIconArrowDropDown, tylIconScheduleSend, tylIconDeleteOutline, tylIconBookmarkBorder]);

const splitMenu = document.querySelector('#split-menu') as IMenuComponent;
splitMenu.options = [
{ label: 'Schedule send', value: 'schedule', leadingIcon: 'schedule_send', leadingIconType: 'component' },
{ label: 'Delete', value: 'delete', leadingIcon: 'delete_outline', leadingIconType: 'component' },
{ label: 'Save draft', value: 'save', leadingIcon: 'bookmark_border', leadingIconType: 'component' }
];

const variantSelect = document.querySelector('#opt-variant') as ISelectComponent;
variantSelect.addEventListener('change', ({ detail: variant }: CustomEvent<SplitButtonVariant>) => {
getSplitButtons().forEach(splitButton => splitButton.variant = variant);
});

const disabledToggle = document.querySelector('#opt-disabled') as ISwitchComponent;
disabledToggle.addEventListener('forge-switch-change', ({ detail: selected }) => {
getSplitButtons().forEach(splitButton => splitButton.disabled = selected);
});

const denseToggle = document.querySelector('#opt-dense') as ISwitchComponent;
denseToggle.addEventListener('forge-switch-change', ({ detail: selected }) => {
getSplitButtons().forEach(splitButton => splitButton.dense = selected);
});

const pillToggle = document.querySelector('#opt-pill') as ISwitchComponent;
pillToggle.addEventListener('forge-switch-change', ({ detail: selected }) => {
getSplitButtons().forEach(splitButton => splitButton.pill = selected);
});

function getSplitButtons(): ISplitButtonComponent[] {
return Array.from(document.querySelectorAll<ISplitButtonComponent>('forge-split-button'));
}
1 change: 1 addition & 0 deletions src/dev/src/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
{ "label": "Select", "path": "/pages/select/select.html", "tags": ["form", "field"] },
{ "label": "Skeleton", "path": "/pages/skeleton/skeleton.html" },
{ "label": "Slider", "path": "/pages/slider/slider.html", "tags": ["form"] },
{ "label": "Split button", "path": "/pages/split-button/split-button.html" },
{ "label": "Split view", "path": "/pages/split-view/split-view.html", "tags": ["form"] },
{ "label": "Stack", "path": "/pages/stack/stack.html" },
{ "label": "State layer", "path": "/pages/state-layer/state-layer.html", "tags": ["ripple", "hover", "focus", "active", "pressed"] },
Expand Down
6 changes: 3 additions & 3 deletions src/lib/button/_core.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
z-index: 0;

box-sizing: border-box;
min-block-size: #{token(min-height)};
min-inline-size: #{token(min-width)};
height: #{token(height)};
inline-size: 100%;
border-width: #{token(border-width)};
border-style: #{token(border-style)};
Expand Down Expand Up @@ -108,7 +108,7 @@

@mixin link {
@include override(color, link-color);
@include override(height, link-height);
@include override(min-height, link-min-height);
@include override(padding, link-padding);
@include override(focus-indicator-offset, link-focus-indicator-offset);

Expand Down Expand Up @@ -154,7 +154,7 @@
}

@mixin dense {
@include override(height, dense-height);
@include override(min-height, dense-min-height);
}

@mixin pill {
Expand Down
6 changes: 3 additions & 3 deletions src/lib/core/styles/tokens/button/_tokens.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ $tokens: (
shape: utils.module-val(button, shape, shape.variable(medium)),

// Base
height: utils.module-val(button, height, 36px),
min-height: utils.module-val(button, min-height, 36px),
min-width: utils.module-val(button, min-width, 64px),
spacing: utils.module-val(button, spacing, spacing.variable(xsmall)),
border-width: utils.module-val(button, border-width, medium),
Expand Down Expand Up @@ -70,7 +70,7 @@ $tokens: (
// Link
link-color: utils.module-ref(button, link-color, primary-color),
link-text-decoration: utils.module-val(button, link-text-decoration, underline),
link-height: utils.module-val(button, link-height, auto),
link-min-height: utils.module-val(button, link-min-height, auto),
link-padding: utils.module-val(button, link-padding, 0),
link-line-height: utils.module-val(button, link-line-height, normal),
link-width: utils.module-val(button, link-width, auto),
Expand All @@ -87,7 +87,7 @@ $tokens: (
disabled-shadow: utils.module-val(button, disabled-shadow, none),

// Dense
dense-height: utils.module-val(button, dense-height, 24px),
dense-min-height: utils.module-val(button, dense-min-height, 24px),

// Pill
pill-shape: utils.module-val(button, pill-shape, shape.variable(full)),
Expand Down
12 changes: 8 additions & 4 deletions src/lib/core/styles/tokens/focus-indicator/_tokens.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@
@use '../../utils';

$tokens: (
width: utils.module-val(focus-indicator, width, border.variable(medium)),
active-width: utils.module-val(focus-indicator, active-width, 6px),

color: utils.module-val(focus-indicator, color, theme.variable(primary)),
duration: utils.module-val(focus-indicator, duration, animation.variable(duration-long4)),
outward-offset: utils.module-val(focus-indicator, outward-offset, spacing.variable(xxsmall)),
inward-offset: utils.module-val(focus-indicator, inward-offset, 0px), // Requires unit
shape: utils.module-val(focus-indicator, shape, shape.variable(extra-small)), // Requires unit
width: utils.module-val(focus-indicator, width, border.variable(medium)),

duration: utils.module-val(focus-indicator, duration, animation.variable(duration-long4)),
easing: utils.module-val(focus-indicator, easing, animation.variable(easing-emphasized)),

shape-start-start: utils.module-ref(focus-indicator, shape-start-start, shape),
shape-start-end: utils.module-ref(focus-indicator, shape-start-end, shape),
shape-end-end: utils.module-ref(focus-indicator, shape-end-end, shape),
shape-end-start: utils.module-ref(focus-indicator, shape-end-start, shape),

outward-offset: utils.module-val(focus-indicator, outward-offset, spacing.variable(xxsmall)),
inward-offset: utils.module-val(focus-indicator, inward-offset, 0px), // Requires unit
offset-block: utils.module-val(focus-indicator, offset-block, 0),
offset-inline: utils.module-val(focus-indicator, offset-inline, 0)
) !default;
Expand Down
16 changes: 16 additions & 0 deletions src/lib/core/styles/tokens/split-button/_tokens.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@use 'sass:map';
@use '../../utils';
@use '../../border';
@use '../button/tokens' as button;

$tokens: (
min-width: utils.module-val(split-button, min-width, 0),
gap: utils.module-val(split-button, gap, border.variable(thin)),

focus-indicator-offset: utils.module-val(split-button, focus-indicator-offset, button.get(focus-indicator-offset)),
focus-indicator-divider-offset: utils.module-ref(split-button, focus-indicator-divider-offset, gap)
) !default;

@function get($key) {
@return map.get($tokens, $key);
}
1 change: 0 additions & 1 deletion src/lib/core/styles/tokens/typography/_tokens.label.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ $label: utils.inherit-map(core.$base, (
$button: utils.inherit-map(core.$base, (
font-size: type-utils.font-size-relative(button, font-size, '0875'),
font-weight: weight.value(medium),
line-height: type-utils.font-size-relative(button, line-height, '2250'),
letter-spacing: type-utils.calc-letter-spacing(1, scale.value('0875'))
)) !default;

Expand Down
2 changes: 2 additions & 0 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import { ScaffoldComponent } from './scaffold';
import { OptionComponent, OptionGroupComponent, SelectComponent } from './select';
import { SkeletonComponent } from './skeleton';
import { SliderComponent } from './slider';
import { SplitButtonComponent } from './split-button';
import { SplitViewComponent } from './split-view';
import { StateLayerComponent } from './state-layer';
import { StepComponent, StepperComponent } from './stepper';
Expand Down Expand Up @@ -131,6 +132,7 @@ export * from './scaffold';
export * from './select';
export * from './skeleton';
export * from './slider';
export * from './split-button';
export * from './split-view';
export * from './state-layer';
export * from './stepper';
Expand Down
2 changes: 1 addition & 1 deletion src/lib/menu/menu.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
:host {
display: inline-block;
display: inline-flex;
}

:host([hidden]) {
Expand Down
1 change: 0 additions & 1 deletion src/lib/slider/_token-utils.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
@use '../core/styles/utils';
@use '../core/styles/tokens/slider/tokens';
@use '../core/styles/tokens/token-utils';

Expand Down
2 changes: 1 addition & 1 deletion src/lib/slider/slider-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export interface ISliderAdapter extends IBaseAdapter {
setEndAriaLabel(value: string | null): void;
}

export class SliderAdapter extends BaseAdapter<ISliderComponent> {
export class SliderAdapter extends BaseAdapter<ISliderComponent> implements ISliderAdapter {
private readonly _rootElement: HTMLElement;
private readonly _trackElement: HTMLElement;
private readonly _handleContainerElement: HTMLElement;
Expand Down
7 changes: 7 additions & 0 deletions src/lib/split-button/_configuration.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@use './token-utils' as *;

@mixin configuration {
@include tokens;

#{declare(focus-indicator-offset-adjusted)}: calc(#{token(focus-indicator-offset)} + #{token(focus-indicator-divider-offset)} * 2);
}
25 changes: 25 additions & 0 deletions src/lib/split-button/_token-utils.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@use '../core/styles/tokens/split-button/tokens';
@use '../core/styles/tokens/token-utils';

$_module: split-button;
$_tokens: tokens.$tokens;

@mixin provide-theme($theme) {
@include token-utils.provide-theme($_module, $_tokens, $theme);
}

@function token($name, $type: token) {
@return token-utils.token($_module, $_tokens, $name, $type);
}

@function declare($token) {
@return token-utils.declare($_module, $token);
}

@mixin override($token, $token-or-value, $type: token) {
@include token-utils.override($_module, $_tokens, $token, $token-or-value, $type);
}

@mixin tokens($includes: null, $excludes: null) {
@include token-utils.tokens($_module, $_tokens, $includes, $excludes);
}
4 changes: 4 additions & 0 deletions src/lib/split-button/build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "../../../node_modules/@tylertech/forge-cli/config/build-schema.json",
"extends": "../build.json"
}
2 changes: 2 additions & 0 deletions src/lib/split-button/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@forward './configuration';
@forward './token-utils' show provide-theme;
12 changes: 12 additions & 0 deletions src/lib/split-button/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineCustomElement } from '@tylertech/forge-core';

import { SplitButtonComponent } from './split-button';

export * from './split-button-adapter';
export * from './split-button-constants';
export * from './split-button-foundation';
export * from './split-button';

export function defineSplitButtonComponent(): void {
defineCustomElement(SplitButtonComponent);
}
Loading

0 comments on commit e21deef

Please sign in to comment.