diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index 56011ad8e..ee27ff5bb 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -30,6 +30,8 @@ export default { { text: 'Modal', link: '/components/modal' }, { text: 'Dropdown Select', link: '/components/dropdown-select' }, { text: 'Dropdown Button', link: '/components/dropdown-button' }, + { text: 'Popout Menu', link: '/components/popout-menu' }, + { text: 'Overflow Menu', link: '/components/overflow-menu' }, { text: 'Project Card', link: '/components/project-card' }, { text: 'Environment Indicator', link: '/components/environment-indicator' }, { text: 'Categories', link: '/components/categories' }, diff --git a/docs/components/button.md b/docs/components/button.md index 5fdd55810..3ceb5fee7 100644 --- a/docs/components/button.md +++ b/docs/components/button.md @@ -1,35 +1,109 @@ -# Button +# Buttons + +## Standard - - - - - - - - - - - - - - + + + + + ```vue - - - - - - - - - - - - - - + + + + + +``` + +## Large + + + + + + + +```vue + + + +``` + +## Outline + + + + + + +```vue + + +``` + +## Transparent + + + + + + + +```vue + + + +``` + +## Hover-filled + + + + + + + + +```vue + + + + +``` + +## Hover-filled-only + + + + + + + + +```vue + + + + +``` + +## Icon-only + + + + + + + + + +```vue + + + + + ``` diff --git a/docs/components/overflow-menu.md b/docs/components/overflow-menu.md new file mode 100644 index 000000000..bd80ad59c --- /dev/null +++ b/docs/components/overflow-menu.md @@ -0,0 +1,94 @@ +# Overflow Menu + + + More options... + + + + + + + + +```vue + + More options... + + + + +``` diff --git a/docs/components/popout-menu.md b/docs/components/popout-menu.md new file mode 100644 index 000000000..31d11de08 --- /dev/null +++ b/docs/components/popout-menu.md @@ -0,0 +1,76 @@ +# Popout Menu + + + Bottom going left + + + + Bottom going right + + + + Top going left + + + + Top going right + + + + Left going up + + + + Left going down + + + + Right going up + + + + Right going down + + + + +```vue + + Bottom going right + + +``` diff --git a/lib/assets/icons/bookmark.svg b/lib/assets/icons/bookmark.svg new file mode 100644 index 000000000..fbe559bc5 --- /dev/null +++ b/lib/assets/icons/bookmark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/assets/icons/copy.svg b/lib/assets/icons/copy.svg new file mode 100644 index 000000000..f3b629c6b --- /dev/null +++ b/lib/assets/icons/copy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/assets/icons/more-horizontal.svg b/lib/assets/icons/more-horizontal.svg new file mode 100644 index 000000000..65d9a0563 --- /dev/null +++ b/lib/assets/icons/more-horizontal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/assets/icons/more-vertical.svg b/lib/assets/icons/more-vertical.svg new file mode 100644 index 000000000..98f4a4dfe --- /dev/null +++ b/lib/assets/icons/more-vertical.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/assets/styles/classes.scss b/lib/assets/styles/classes.scss index 588ed6939..3eaa4089b 100644 --- a/lib/assets/styles/classes.scss +++ b/lib/assets/styles/classes.scss @@ -266,10 +266,13 @@ a, &:focus-visible:not(&:disabled), &:hover:not(&:disabled) { cursor: pointer; - filter: brightness(0.85); + + &:not(.btn-outline.btn-hover-filled, .btn-transparent) { + filter: brightness(0.85); + } } - &:active:not(&:disabled) { + &:active:not(&:disabled, .btn-outline.btn-hover-filled, .btn-transparent) { filter: brightness(0.8); } @@ -321,44 +324,121 @@ a, .btn { @extend .button-base; - --text-color: var(--color-contrast); - --background-color: var(--color-button-bg); - --shadow: var(--shadow-inset-sm), 0 0 0 0 transparent; + --_text-color: var(--color-base); + --_background-color: var(--color-button-bg); + --_accent-color: var(--color-base); + --_shadow: var(--shadow-inset-sm), 0 0 0 0 transparent; - &.btn-outline { - --background-color: var(--color-contrast); - --text-color: var(--color-raised-bg); + &.btn-outline, + &.btn-transparent { box-sizing: border-box; background-color: transparent; - border: 2px solid var(--background-color); - color: var(--background-color); - - padding-block: calc(var(--gap-sm) - 2px); + transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out, + color 0.2s ease-in-out; + box-shadow: none; } - &.btn-raised { - --shadow: var(--shadow-inset-sm), var(--shadow-raised); - --background-color: var(--color-raised-bg); + &.btn-transparent { + --_accent-color: var(--color-base); + color: var(--_accent-color); + + &.btn-hover-filled-only { + color: var(--color-base); + } + + &:focus-visible:not(&:disabled), + &:hover:not(&:disabled) { + background-color: var(--color-button-bg); + + &.btn-hover-filled, + &.btn-hover-filled-only { + color: var(--_text-color); + background-color: var(--_background-color); + } + } + } + + &.btn-outline { + --_accent-color: var(--color-contrast); + border: 2px solid var(--_accent-color); + padding-block: calc(var(--gap-sm) - 2px); + color: var(--_background-color); + + &.btn-hover-filled-only { + color: var(--color-contrast); + border-color: var(--color-contrast); + } + + &:focus-visible:not(&:disabled), + &:hover:not(&:disabled) { + &.btn-hover-filled, + &.btn-hover-filled-only { + border-color: var(--_accent-color); + color: var(--_text-color); + background-color: var(--_background-color); + } + } } &.btn-danger { - --text-color: var(--color-accent-contrast); - --background-color: var(--color-red); + --_text-color: var(--color-accent-contrast); + --_background-color: var(--color-red); + --_accent-color: var(--color-red); } &.btn-primary { - --text-color: var(--color-accent-contrast); - --background-color: var(--color-brand); + --_text-color: var(--color-accent-contrast); + --_background-color: var(--color-brand); + --_accent-color: var(--color-brand); } &.btn-secondary { - --background-color: var(--color-brand-highlight); + --_text-color: var(--color-contrast); + --_background-color: var(--color-brand-highlight); + --_accent-color: var(--color-brand-highlight); } &.btn-highlight { - --text-color: var(--color-accent-contrast); - --background-color: var(--color-orange); + --_text-color: var(--color-accent-contrast); + --_background-color: var(--color-orange); + --_accent-color: var(--color-orange); + } + + &.btn-red { + --_text-color: var(--color-accent-contrast); + --_background-color: var(--color-red); + --_accent-color: var(--color-red); + } + + &.btn-orange { + --_text-color: var(--color-accent-contrast); + --_background-color: var(--color-orange); + --_accent-color: var(--color-orange); + } + + &.btn-green { + --_text-color: var(--color-accent-contrast); + --_background-color: var(--color-green); + --_accent-color: var(--color-green); + } + + &.btn-blue { + --_text-color: var(--color-accent-contrast); + --_background-color: var(--color-blue); + --_accent-color: var(--color-blue); + } + + &.btn-purple { + --_text-color: var(--color-accent-contrast); + --_background-color: var(--color-purple); + --_accent-color: var(--color-purple); + } + + &.btn-gray { + --_text-color: var(--color-accent-contrast); + --_background-color: var(--color-gray); + --_accent-color: var(--color-gray); } &.btn-large { @@ -368,25 +448,26 @@ a, box-sizing: border-box; - color: var(--text-color); - background-color: var(--background-color); - box-shadow: var(--shadow); + color: var(--_text-color); + background-color: var(--_background-color); + box-shadow: var(--_shadow); border-radius: var(--radius-md); - padding-inline: var(--gap-lg); - padding-block: var(--gap-sm); + padding: var(--gap-sm) var(--gap-lg); display: flex; align-items: center; + justify-content: center; cursor: pointer; width: fit-content; height: fit-content; text-decoration: none; + gap: 0.5rem; + line-height: 1.25rem; svg { - width: 1.1rem; - height: 1.1rem; - margin-right: 0.5rem; + width: 1.25rem; + height: 1.25rem; } :deep(.external-icon) { @@ -398,17 +479,7 @@ a, } &.icon-only { - padding: 0; - height: 2.25rem; - width: 2.25rem; - - svg { - min-width: 1.25rem; - max-width: 1.25rem; - min-height: 1.25rem; - max-height: 1.25rem; - margin: auto; - } + padding: var(--gap-sm); } &.transparent { diff --git a/lib/assets/styles/variables.scss b/lib/assets/styles/variables.scss index 14c023cdd..5e9a1343f 100644 --- a/lib/assets/styles/variables.scss +++ b/lib/assets/styles/variables.scss @@ -25,6 +25,7 @@ html { --color-button-bg: hsl(220, 13%, 91%); --color-base: hsl(221, 39%, 11%); + --color-secondary: #6b7280; --color-contrast: #1a202c; --color-accent-contrast: #ffffff; @@ -67,6 +68,7 @@ html { --color-button-bg: hsl(222, 13%, 30%); --color-base: var(--dark-color-base); + --color-secondary: #96a2b0; --color-contrast: var(--dark-color-contrast); --color-accent-contrast: #000000; diff --git a/lib/components/base/Button.vue b/lib/components/base/Button.vue index 8bddc3018..4d9a4480d 100644 --- a/lib/components/base/Button.vue +++ b/lib/components/base/Button.vue @@ -32,9 +32,23 @@ const props = defineProps({ type: Boolean, default: false, }, + transparent: { + type: Boolean, + default: false, + }, + hoverFilled: { + type: Boolean, + default: false, + }, + hoverFilledOnly: { + type: Boolean, + default: false, + }, }) -const accentedButton = computed(() => ['danger', 'primary'].includes(props.color)) +const accentedButton = computed(() => + ['danger', 'primary', 'red', 'orange', 'green', 'blue', 'purple', 'gray'].includes(props.color) +)