chore: hoppscotch-ui improvements (#3497)

Co-authored-by: Liyas Thomas <liyascthomas@gmail.com>
Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
This commit is contained in:
Anwarul Islam
2023-12-06 00:38:44 +06:00
committed by GitHub
parent 18864bfecf
commit 6fa722df7b
69 changed files with 726 additions and 640 deletions

View File

@@ -5,5 +5,4 @@ module.exports = {
printWidth: 80, printWidth: 80,
useTabs: false, useTabs: false,
tabWidth: 2, tabWidth: 2,
plugins: ["prettier-plugin-tailwindcss"],
} }

View File

@@ -29,14 +29,6 @@
@apply antialiased; @apply antialiased;
accent-color: var(--accent-color); accent-color: var(--accent-color);
font-variant-ligatures: common-ligatures; font-variant-ligatures: common-ligatures;
// Colors
--info-color: #ec4899;
--success-color: #10b981;
--blue-color: #3b82f6;
--warning-color: #f59e0b;
--cl-error-color: #ef4444;
--sv-error-color: #dc2626;
} }
::-webkit-scrollbar-track { ::-webkit-scrollbar-track {
@@ -65,7 +57,7 @@ input::placeholder,
textarea::placeholder, textarea::placeholder,
.cm-placeholder { .cm-placeholder {
@apply text-secondary; @apply text-secondary;
@apply opacity-50; @apply opacity-50 #{!important};
} }
input, input,
@@ -84,7 +76,7 @@ body {
@apply font-medium; @apply font-medium;
@apply select-none; @apply select-none;
@apply overflow-x-hidden; @apply overflow-x-hidden;
@apply leading-body; @apply leading-body #{!important};
animation: fade 300ms forwards; animation: fade 300ms forwards;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none; -webkit-touch-callout: none;
@@ -182,7 +174,7 @@ a {
@apply font-semibold; @apply font-semibold;
@apply px-2 py-1; @apply px-2 py-1;
@apply truncate; @apply truncate;
@apply leading-normal; @apply leading-body;
@apply items-center; @apply items-center;
kbd { kbd {
@@ -229,7 +221,7 @@ a {
@apply overflow-y-auto; @apply overflow-y-auto;
@apply text-body text-secondary; @apply text-body text-secondary;
@apply p-2; @apply p-2;
@apply leading-normal; @apply leading-body;
@apply focus:outline-none; @apply focus:outline-none;
scroll-behavior: smooth; scroll-behavior: smooth;
@@ -261,7 +253,7 @@ a {
hr { hr {
@apply border-b border-dividerLight; @apply border-b border-dividerLight;
@apply my-2; @apply my-2 #{!important};
} }
.heading { .heading {
@@ -350,44 +342,28 @@ pre.ace_editor {
} }
} }
.select-wrapper {
@apply flex flex-1;
@apply relative;
@apply after:absolute;
@apply after:flex;
@apply after:inset-y-0;
@apply after:items-center;
@apply after:justify-center;
@apply after:pointer-events-none;
@apply after:font-icon;
@apply after:text-current;
@apply after:right-3;
@apply after:content-["\e5cf"];
@apply after:text-lg;
}
.info-response { .info-response {
color: var(--info-color); color: var(--status-info-color);
} }
.success-response { .success-response {
color: var(--success-color); color: var(--status-success-color);
} }
.redir-response { .redirect-response {
color: var(--warning-color); color: var(--status-redirect-color);
} }
.cl-error-response { .critical-error-response {
color: var(--cl-error-color); color: var(--status-critical-error-color);
} }
.sv-error-response { .server-error-response {
color: var(--sv-error-color); color: var(--status-server-error-color);
} }
.missing-data-response { .missing-data-response {
@apply text-secondaryLight; color: var(--status-missing-data-color);
} }
.toasted-container { .toasted-container {
@@ -537,12 +513,12 @@ pre.ace_editor {
@apply inline-flex; @apply inline-flex;
@apply font-sans; @apply font-sans;
@apply text-tiny; @apply text-tiny;
@apply bg-divider; @apply bg-dividerLight;
@apply rounded; @apply rounded;
@apply ml-2; @apply ml-2;
@apply px-1; @apply px-1;
@apply min-w-5; @apply min-w-[1.25rem];
@apply min-h-5; @apply min-h-[1.25rem];
@apply items-center; @apply items-center;
@apply justify-center; @apply justify-center;
@apply border border-dividerDark; @apply border border-dividerDark;

View File

@@ -1,89 +1,89 @@
@mixin green-theme { @mixin green-theme {
--accent-color: #10b981; --accent-color: theme("colors.emerald.500");
--accent-light-color: #34d399; --accent-light-color: theme("colors.emerald.400");
--accent-dark-color: #059669; --accent-dark-color: theme("colors.emerald.600");
--accent-contrast-color: #fff; --accent-contrast-color: theme("colors.white");
--gradient-from-color: #a7f3d0; --gradient-from-color: theme("colors.emerald.400");
--gradient-via-color: #34d399; --gradient-via-color: theme("colors.emerald.500");
--gradient-to-color: #059669; --gradient-to-color: theme("colors.emerald.600");
} }
@mixin teal-theme { @mixin teal-theme {
--accent-color: #14b8a6; --accent-color: theme("colors.teal.500");
--accent-light-color: #2dd4bf; --accent-light-color: theme("colors.teal.400");
--accent-dark-color: #0d9488; --accent-dark-color: theme("colors.teal.600");
--accent-contrast-color: #fff; --accent-contrast-color: theme("colors.white");
--gradient-from-color: #99f6e4; --gradient-from-color: theme("colors.teal.400");
--gradient-via-color: #2dd4bf; --gradient-via-color: theme("colors.teal.500");
--gradient-to-color: #0d9488; --gradient-to-color: theme("colors.teal.600");
} }
@mixin blue-theme { @mixin blue-theme {
--accent-color: #3b82f6; --accent-color: theme("colors.blue.500");
--accent-light-color: #60a5fa; --accent-light-color: theme("colors.blue.400");
--accent-dark-color: #2563eb; --accent-dark-color: theme("colors.blue.600");
--accent-contrast-color: #fff; --accent-contrast-color: theme("colors.white");
--gradient-from-color: #bfdbfe; --gradient-from-color: theme("colors.blue.400");
--gradient-via-color: #60a5fa; --gradient-via-color: theme("colors.blue.500");
--gradient-to-color: #2563eb; --gradient-to-color: theme("colors.blue.600");
} }
@mixin indigo-theme { @mixin indigo-theme {
--accent-color: #6366f1; --accent-color: theme("colors.indigo.500");
--accent-light-color: #818cf8; --accent-light-color: theme("colors.indigo.400");
--accent-dark-color: #4f46e5; --accent-dark-color: theme("colors.indigo.600");
--accent-contrast-color: #fff; --accent-contrast-color: theme("colors.white");
--gradient-from-color: #c7d2fe; --gradient-from-color: theme("colors.indigo.400");
--gradient-via-color: #818cf8; --gradient-via-color: theme("colors.indigo.500");
--gradient-to-color: #4f46e5; --gradient-to-color: theme("colors.indigo.600");
} }
@mixin purple-theme { @mixin purple-theme {
--accent-color: #8b5cf6; --accent-color: theme("colors.purple.500");
--accent-light-color: #a78bfa; --accent-light-color: theme("colors.purple.400");
--accent-dark-color: #7c3aed; --accent-dark-color: theme("colors.purple.600");
--accent-contrast-color: #fff; --accent-contrast-color: theme("colors.white");
--gradient-from-color: #ddd6fe; --gradient-from-color: theme("colors.purple.400");
--gradient-via-color: #a78bfa; --gradient-via-color: theme("colors.purple.500");
--gradient-to-color: #7c3aed; --gradient-to-color: theme("colors.purple.600");
} }
@mixin yellow-theme { @mixin yellow-theme {
--accent-color: #f59e0b; --accent-color: theme("colors.amber.500");
--accent-light-color: #fbbf24; --accent-light-color: theme("colors.amber.400");
--accent-dark-color: #d97706; --accent-dark-color: theme("colors.amber.600");
--accent-contrast-color: #fff; --accent-contrast-color: theme("colors.white");
--gradient-from-color: #fde68a; --gradient-from-color: theme("colors.amber.400");
--gradient-via-color: #fbbf24; --gradient-via-color: theme("colors.amber.500");
--gradient-to-color: #d97706; --gradient-to-color: theme("colors.amber.600");
} }
@mixin orange-theme { @mixin orange-theme {
--accent-color: #f97316; --accent-color: theme("colors.orange.500");
--accent-light-color: #fb923c; --accent-light-color: theme("colors.orange.400");
--accent-dark-color: #ea580c; --accent-dark-color: theme("colors.orange.600");
--accent-contrast-color: #fff; --accent-contrast-color: theme("colors.white");
--gradient-from-color: #fed7aa; --gradient-from-color: theme("colors.orange.400");
--gradient-via-color: #fb923c; --gradient-via-color: theme("colors.orange.500");
--gradient-to-color: #ea580c; --gradient-to-color: theme("colors.orange.600");
} }
@mixin red-theme { @mixin red-theme {
--accent-color: #ef4444; --accent-color: theme("colors.red.500");
--accent-light-color: #f87171; --accent-light-color: theme("colors.red.400");
--accent-dark-color: #dc2626; --accent-dark-color: theme("colors.red.600");
--accent-contrast-color: #fff; --accent-contrast-color: theme("colors.white");
--gradient-from-color: #fecaca; --gradient-from-color: theme("colors.red.400");
--gradient-via-color: #f87171; --gradient-via-color: theme("colors.red.500");
--gradient-to-color: #dc2626; --gradient-to-color: theme("colors.red.600");
} }
@mixin pink-theme { @mixin pink-theme {
--accent-color: #ec4899; --accent-color: theme("colors.pink.500");
--accent-light-color: #f472b6; --accent-light-color: theme("colors.pink.400");
--accent-dark-color: #db2777; --accent-dark-color: theme("colors.pink.600");
--accent-contrast-color: #fff; --accent-contrast-color: theme("colors.white");
--gradient-from-color: #fbcfe8; --gradient-from-color: theme("colors.pink.400");
--gradient-via-color: #f472b6; --gradient-via-color: theme("colors.pink.500");
--gradient-to-color: #db2777; --gradient-to-color: theme("colors.pink.600");
} }

View File

@@ -1,17 +1,16 @@
@mixin base-theme { @mixin base-theme {
--font-sans: "Inter Variable", sans-serif; --font-sans: "Inter Variable", sans-serif;
--font-icon: "Material Symbols Rounded Variable";
--font-mono: "Roboto Mono Variable", monospace; --font-mono: "Roboto Mono Variable", monospace;
--font-size-body: 0.75rem; --font-size-body: 0.75rem;
--font-size-tiny: 0.688rem; --font-size-tiny: 0.625rem;
--line-height-body: 1rem; --line-height-body: 1rem;
--upper-primary-sticky-fold: 4.125rem; --upper-primary-sticky-fold: 4.125rem;
--upper-secondary-sticky-fold: 6.188rem; --upper-secondary-sticky-fold: 6.188rem;
--upper-tertiary-sticky-fold: 8.25rem; --upper-tertiary-sticky-fold: 8.25rem;
--upper-fourth-sticky-fold: 10.2rem; --upper-fourth-sticky-fold: 10.2rem;
--upper-mobile-primary-sticky-fold: 6.625rem; --upper-mobile-primary-sticky-fold: 6.75rem;
--upper-mobile-secondary-sticky-fold: 8.688rem; --upper-mobile-secondary-sticky-fold: 8.813rem;
--upper-mobile-sticky-fold: 10.75rem; --upper-mobile-sticky-fold: 10.875rem;
--upper-mobile-tertiary-sticky-fold: 8.25rem; --upper-mobile-tertiary-sticky-fold: 8.25rem;
--lower-primary-sticky-fold: 3rem; --lower-primary-sticky-fold: 3rem;
--lower-secondary-sticky-fold: 5.063rem; --lower-secondary-sticky-fold: 5.063rem;
@@ -21,67 +20,121 @@
} }
@mixin light-theme { @mixin light-theme {
--primary-color: #ffffff; --primary-color: theme("colors.white");
--primary-light-color: #f9fafb; --primary-light-color: theme("colors.gray.50");
--primary-dark-color: #f3f4f6; --primary-dark-color: theme("colors.gray.100");
--primary-contrast-color: #fdfdfd; --primary-contrast-color: #fdfdfd;
--secondary-color: #6b7280; --secondary-color: theme("colors.gray.500");
--secondary-light-color: #9ca3af; --secondary-light-color: theme("colors.gray.400");
--secondary-dark-color: #111827; --secondary-dark-color: theme("colors.gray.900");
--divider-color: #f3f4f6; --divider-color: theme("colors.gray.100");
--divider-light-color: #f3f4f6; --divider-light-color: theme("colors.gray.100");
--divider-dark-color: #d1d5db; --divider-dark-color: theme("colors.gray.300");
--banner-info-color: theme("colors.stone.100");
--banner-warning-color: theme("colors.yellow.100");
--banner-error-color: theme("colors.red.100");
--tooltip-color: theme("colors.neutral.800");
--popover-color: theme("colors.white");
--method-get-color: theme("colors.green.500");
--method-post-color: theme("colors.amber.500");
--method-put-color: theme("colors.blue.500");
--method-patch-color: theme("colors.purple.500");
--method-delete-color: theme("colors.red.500");
--method-head-color: theme("colors.lime.500");
--method-options-color: theme("colors.pink.500");
--method-default-color: theme("colors.gray.500");
--status-info-color: theme("colors.blue.500");
--status-success-color: theme("colors.green.500");
--status-redirect-color: theme("colors.amber.500");
--status-critical-error-color: theme("colors.red.500");
--status-server-error-color: theme("colors.rose.500");
--status-missing-data-color: theme("colors.slate.500");
--info-color: #fef3c7;
--warning-color: #fef9c3;
--error-color: #fee2e2;
--tooltip-color: #262626;
--popover-color: #ffffff;
--editor-theme: "textmate"; --editor-theme: "textmate";
} }
@mixin dark-theme { @mixin dark-theme {
--primary-color: #181818; --primary-color: #181818;
--primary-light-color: #1c1c1e; --primary-light-color: #1c1c1e;
--primary-dark-color: #262626; --primary-dark-color: theme("colors.neutral.800");
--primary-contrast-color: #171717; --primary-contrast-color: theme("colors.neutral.900");
--secondary-color: #a3a3a3; --secondary-color: theme("colors.neutral.400");
--secondary-light-color: #737373; --secondary-light-color: theme("colors.neutral.500");
--secondary-dark-color: #fafafa; --secondary-dark-color: theme("colors.zinc.50");
--divider-color: #262626; --divider-color: #1f1f1f;
--divider-light-color: #1f1f1f; --divider-light-color: #1f1f1f;
--divider-dark-color: #2d2d2d; --divider-dark-color: theme("colors.zinc.800");
--info-color: #292524; --banner-info-color: theme("colors.stone.800");
--warning-color: #854d0e; --banner-warning-color: theme("colors.yellow.800");
--error-color: #991b1b; --banner-error-color: theme("colors.red.800");
--tooltip-color: #f5f5f5;
--tooltip-color: theme("colors.neutral.100");
--popover-color: #1b1b1b; --popover-color: #1b1b1b;
--method-get-color: theme("colors.emerald.500");
--method-post-color: theme("colors.yellow.500");
--method-put-color: theme("colors.sky.500");
--method-patch-color: theme("colors.violet.500");
--method-delete-color: theme("colors.rose.500");
--method-head-color: theme("colors.teal.500");
--method-options-color: theme("colors.indigo.500");
--method-default-color: theme("colors.neutral.500");
--status-info-color: theme("colors.blue.500");
--status-success-color: theme("colors.green.500");
--status-redirect-color: theme("colors.amber.500");
--status-critical-error-color: theme("colors.red.500");
--status-server-error-color: theme("colors.rose.500");
--status-missing-data-color: theme("colors.slate.500");
--editor-theme: "merbivore_soft"; --editor-theme: "merbivore_soft";
} }
@mixin black-theme { @mixin black-theme {
--primary-color: #0f0f0f; --primary-color: #0f0f0f;
--primary-light-color: #171717; --primary-light-color: theme("colors.neutral.900");
--primary-dark-color: #181818; --primary-dark-color: #181818;
--primary-contrast-color: #0f0f0f; --primary-contrast-color: #0f0f0f;
--secondary-color: #a3a3a3; --secondary-color: theme("colors.neutral.400");
--secondary-light-color: #737373; --secondary-light-color: theme("colors.neutral.500");
--secondary-dark-color: #f5f5f5; --secondary-dark-color: theme("colors.neutral.50");
--divider-color: #1c1c1e; --divider-color: theme("colors.neutral.900");
--divider-light-color: #181818; --divider-light-color: theme("colors.neutral.900");
--divider-dark-color: #323232; --divider-dark-color: theme("colors.zinc.800");
--banner-info-color: theme("colors.stone.900");
--banner-warning-color: theme("colors.yellow.900");
--banner-error-color: theme("colors.red.900");
--tooltip-color: theme("colors.neutral.100");
--popover-color: theme("colors.stone.950");
--method-get-color: theme("colors.emerald.500");
--method-post-color: theme("colors.yellow.500");
--method-put-color: theme("colors.sky.500");
--method-patch-color: theme("colors.violet.500");
--method-delete-color: theme("colors.rose.500");
--method-head-color: theme("colors.teal.500");
--method-options-color: theme("colors.indigo.500");
--method-default-color: theme("colors.zinc.500");
--status-info-color: theme("colors.blue.500");
--status-success-color: theme("colors.green.500");
--status-redirect-color: theme("colors.amber.500");
--status-critical-error-color: theme("colors.red.500");
--status-server-error-color: theme("colors.rose.500");
--status-missing-data-color: theme("colors.slate.500");
--info-color: #1c1917;
--warning-color: #713f12;
--error-color: #7f1d1d;
--tooltip-color: #f5f5f5;
--popover-color: #0f0f0f;
--editor-theme: "twilight"; --editor-theme: "twilight";
} }

View File

@@ -1,41 +1,41 @@
@mixin dark-editor-theme { @mixin light-editor-theme {
--editor-type-color: #a78bfa; --editor-type-color: theme("colors.violet.600");
--editor-name-color: #60a5fa; --editor-name-color: theme("colors.red.600");
--editor-operator-color: #818cf8; --editor-operator-color: theme("colors.indigo.600");
--editor-invalid-color: #f87171; --editor-invalid-color: theme("colors.red.600");
--editor-separator-color: #9ca3af; --editor-separator-color: theme("colors.gray.600");
--editor-meta-color: #9ca3af; --editor-meta-color: theme("colors.gray.600");
--editor-variable-color: #34d399; --editor-variable-color: theme("colors.emerald.600");
--editor-link-color: #22d3ee; --editor-link-color: theme("colors.cyan.600");
--editor-process-color: #e879f9; --editor-process-color: theme("colors.blue.600");
--editor-constant-color: #a78bfa; --editor-constant-color: theme("colors.fuchsia.600");
--editor-keyword-color: #f472b6; --editor-keyword-color: theme("colors.pink.600");
} }
@mixin light-editor-theme { @mixin dark-editor-theme {
--editor-type-color: #7c3aed; --editor-type-color: theme("colors.violet.400");
--editor-name-color: #dc2626; --editor-name-color: theme("colors.blue.400");
--editor-operator-color: #4f46e5; --editor-operator-color: theme("colors.indigo.400");
--editor-invalid-color: #dc2626; --editor-invalid-color: theme("colors.red.400");
--editor-separator-color: #4b5563; --editor-separator-color: theme("colors.gray.400");
--editor-meta-color: #4b5563; --editor-meta-color: theme("colors.gray.400");
--editor-variable-color: #059669; --editor-variable-color: theme("colors.emerald.400");
--editor-link-color: #0891b2; --editor-link-color: theme("colors.cyan.400");
--editor-process-color: #2563eb; --editor-process-color: theme("colors.fuchsia.400");
--editor-constant-color: #c026d3; --editor-constant-color: theme("colors.violet.400");
--editor-keyword-color: #db2777; --editor-keyword-color: theme("colors.pink.400");
} }
@mixin black-editor-theme { @mixin black-editor-theme {
--editor-type-color: #a78bfa; --editor-type-color: theme("colors.violet.400");
--editor-name-color: #e879f9; --editor-name-color: theme("colors.fuchsia.400");
--editor-operator-color: #818cf8; --editor-operator-color: theme("colors.indigo.400");
--editor-invalid-color: #f87171; --editor-invalid-color: theme("colors.red.400");
--editor-separator-color: #9ca3af; --editor-separator-color: theme("colors.gray.400");
--editor-meta-color: #9ca3af; --editor-meta-color: theme("colors.gray.400");
--editor-variable-color: #34d399; --editor-variable-color: theme("colors.emerald.400");
--editor-link-color: #22d3ee; --editor-link-color: theme("colors.cyan.400");
--editor-process-color: #a78bfa; --editor-process-color: theme("colors.violet.400");
--editor-constant-color: #60a5fa; --editor-constant-color: theme("colors.blue.400");
--editor-keyword-color: #f472b6; --editor-keyword-color: theme("colors.pink.400");
} }

View File

@@ -345,7 +345,7 @@
"authorization": "The authorization header will be automatically generated when you send the request.", "authorization": "The authorization header will be automatically generated when you send the request.",
"generate_documentation_first": "Generate documentation first", "generate_documentation_first": "Generate documentation first",
"network_fail": "Unable to reach the API endpoint. Check your network connection or select a different Interceptor and try again.", "network_fail": "Unable to reach the API endpoint. Check your network connection or select a different Interceptor and try again.",
"offline": "You're using Hoppscotch offline. Updates will sync when you're online, based on workspace settings", "offline": "You're using Hoppscotch offline. Updates will sync when you're online, based on workspace settings.",
"offline_short": "You're using Hoppscotch offline.", "offline_short": "You're using Hoppscotch offline.",
"post_request_tests": "Test scripts are written in JavaScript, and are run after the response is received.", "post_request_tests": "Test scripts are written in JavaScript, and are run after the response is received.",
"pre_request_script": "Pre-request scripts are written in JavaScript, and are run before the request is sent.", "pre_request_script": "Pre-request scripts are written in JavaScript, and are run before the request is sent.",

View File

@@ -108,6 +108,7 @@ declare module 'vue' {
HoppSmartProgressRing: typeof import('@hoppscotch/ui')['HoppSmartProgressRing'] HoppSmartProgressRing: typeof import('@hoppscotch/ui')['HoppSmartProgressRing']
HoppSmartRadio: typeof import('@hoppscotch/ui')['HoppSmartRadio'] HoppSmartRadio: typeof import('@hoppscotch/ui')['HoppSmartRadio']
HoppSmartRadioGroup: typeof import('@hoppscotch/ui')['HoppSmartRadioGroup'] HoppSmartRadioGroup: typeof import('@hoppscotch/ui')['HoppSmartRadioGroup']
HoppSmartSelectWrapper: typeof import('@hoppscotch/ui')['HoppSmartSelectWrapper']
HoppSmartSlideOver: typeof import('@hoppscotch/ui')['HoppSmartSlideOver'] HoppSmartSlideOver: typeof import('@hoppscotch/ui')['HoppSmartSlideOver']
HoppSmartSpinner: typeof import('@hoppscotch/ui')['HoppSmartSpinner'] HoppSmartSpinner: typeof import('@hoppscotch/ui')['HoppSmartSpinner']
HoppSmartTab: typeof import('@hoppscotch/ui')['HoppSmartTab'] HoppSmartTab: typeof import('@hoppscotch/ui')['HoppSmartTab']
@@ -215,6 +216,7 @@ declare module 'vue' {
SmartProgressRing: typeof import('./../../hoppscotch-ui/src/components/smart/ProgressRing.vue')['default'] SmartProgressRing: typeof import('./../../hoppscotch-ui/src/components/smart/ProgressRing.vue')['default']
SmartRadio: typeof import('./../../hoppscotch-ui/src/components/smart/Radio.vue')['default'] SmartRadio: typeof import('./../../hoppscotch-ui/src/components/smart/Radio.vue')['default']
SmartRadioGroup: typeof import('./../../hoppscotch-ui/src/components/smart/RadioGroup.vue')['default'] SmartRadioGroup: typeof import('./../../hoppscotch-ui/src/components/smart/RadioGroup.vue')['default']
SmartSelectWrapper: typeof import('./../../hoppscotch-ui/src/components/smart/SelectWrapper.vue')['default']
SmartSlideOver: typeof import('./../../hoppscotch-ui/src/components/smart/SlideOver.vue')['default'] SmartSlideOver: typeof import('./../../hoppscotch-ui/src/components/smart/SlideOver.vue')['default']
SmartSpinner: typeof import('./../../hoppscotch-ui/src/components/smart/Spinner.vue')['default'] SmartSpinner: typeof import('./../../hoppscotch-ui/src/components/smart/Spinner.vue')['default']
SmartTab: typeof import('./../../hoppscotch-ui/src/components/smart/Tab.vue')['default'] SmartTab: typeof import('./../../hoppscotch-ui/src/components/smart/Tab.vue')['default']

View File

@@ -1,25 +1,21 @@
<template> <template>
<div <div
:role="bannerRole" :role="bannerRole"
class="flex items-center justify-between px-4 py-2 text-tiny" class="flex items-center justify-between px-4 py-2 text-tiny text-secondaryDark"
:class="bannerColor" :class="bannerColor"
> >
<div class="flex items-center"> <div class="flex items-center">
<component :is="bannerIcon" class="mr-2 text-secondaryDark" /> <component :is="bannerIcon" class="mr-2" />
<span :class="{ 'hidden sm:inline-flex': banner.alternateText }">
<span class="text-secondaryDark"> {{ banner.text(t) }}
<span v-if="banner.alternateText" class="md:hidden"> </span>
{{ banner.alternateText(t) }} <span v-if="banner.alternateText" class="inline-flex sm:hidden">
</span> {{ banner.alternateText(t) }}
<span :class="{ '<md:hidden': banner.alternateText }">
{{ banner.text(t) }}
</span>
</span> </span>
</div> </div>
<icon-lucide-x <icon-lucide-x
v-if="dismissible" v-if="dismissible"
class="text-white hover:cursor-pointer hover:text-gray-300" class="opacity-50 hover:cursor-pointer hover:opacity-100"
@click="emit('dismiss')" @click="emit('dismiss')"
/> />
</div> </div>
@@ -57,9 +53,9 @@ const ariaRoles: Record<BannerType, string> = {
} }
const bgColors: Record<BannerType, string> = { const bgColors: Record<BannerType, string> = {
info: "bg-info", info: "bg-bannerInfo",
warning: "bg-warning", warning: "bg-bannerWarning",
error: "bg-error", error: "bg-bannerError",
} }
const icons = { const icons = {

View File

@@ -2,25 +2,27 @@
<div> <div>
<header <header
ref="headerRef" ref="headerRef"
class="flex flex-1 flex-shrink-0 items-center justify-between space-x-2 overflow-x-auto overflow-y-hidden px-2 py-2" class="grid grid-cols-5 grid-rows-1 gap-2 overflow-x-auto overflow-y-hidden p-2"
@mousedown.prevent="platform.ui?.appHeader?.onHeaderAreaClick?.()" @mousedown.prevent="platform.ui?.appHeader?.onHeaderAreaClick?.()"
> >
<div <div
class="inline-flex flex-1 items-center justify-start space-x-2" class="col-span-2 flex items-center justify-between space-x-2"
:style="{ :style="{
paddingTop: platform.ui?.appHeader?.paddingTop?.value, paddingTop: platform.ui?.appHeader?.paddingTop?.value,
paddingLeft: platform.ui?.appHeader?.paddingLeft?.value, paddingLeft: platform.ui?.appHeader?.paddingLeft?.value,
}" }"
> >
<HoppButtonSecondary <div class="flex">
class="!font-bold uppercase tracking-wide !text-secondaryDark hover:bg-primaryDark focus-visible:bg-primaryDark" <HoppButtonSecondary
:label="t('app.name')" class="!font-bold uppercase tracking-wide !text-secondaryDark hover:bg-primaryDark focus-visible:bg-primaryDark"
to="/" :label="t('app.name')"
/> to="/"
/>
</div>
</div> </div>
<div class="inline-flex flex-1 items-center justify-center space-x-2"> <div class="col-span-1 flex items-center justify-between space-x-2">
<button <button
class="flex max-w-[15rem] flex-1 cursor-text items-center justify-between self-stretch rounded border border-dividerDark bg-primaryDark px-2 py-1 text-secondaryLight transition hover:border-dividerDark hover:bg-primaryLight hover:text-secondary focus-visible:border-dividerDark focus-visible:bg-primaryLight focus-visible:text-secondary" class="flex h-full flex-1 cursor-text items-center justify-between self-stretch rounded border border-dividerDark bg-primaryDark px-2 text-secondaryLight transition hover:border-dividerDark hover:bg-primaryLight hover:text-secondary focus-visible:border-dividerDark focus-visible:bg-primaryLight focus-visible:text-secondary"
@click="invokeAction('modals.search.toggle')" @click="invokeAction('modals.search.toggle')"
> >
<span class="inline-flex flex-1 items-center"> <span class="inline-flex flex-1 items-center">
@@ -32,169 +34,180 @@
<kbd class="shortcut-key">K</kbd> <kbd class="shortcut-key">K</kbd>
</span> </span>
</button> </button>
<HoppButtonSecondary
v-if="showInstallButton"
v-tippy="{ theme: 'tooltip' }"
:title="t('header.install_pwa')"
:icon="IconDownload"
class="rounded hover:bg-primaryDark focus-visible:bg-primaryDark"
@click="installPWA()"
/>
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip', allowHTML: true }"
:title="`${
mdAndLarger ? t('support.title') : t('app.options')
} <kbd>?</kbd>`"
:icon="IconLifeBuoy"
class="rounded hover:bg-primaryDark focus-visible:bg-primaryDark"
@click="invokeAction('modals.support.toggle')"
/>
</div> </div>
<div class="inline-flex flex-1 items-center justify-end space-x-2"> <div class="col-span-2 flex items-center justify-between space-x-2">
<div <div class="flex">
v-if="currentUser === null"
class="inline-flex items-center space-x-2"
>
<HoppButtonSecondary <HoppButtonSecondary
:icon="IconUploadCloud" v-if="showInstallButton"
:label="t('header.save_workspace')" v-tippy="{ theme: 'tooltip' }"
class="py-1.75 !focus-visible:text-green-600 !hover:text-green-600 hidden border border-green-600/25 bg-green-500/[.15] !text-green-500 hover:border-green-800/50 hover:bg-green-400/10 focus-visible:border-green-800/50 focus-visible:bg-green-400/10 md:flex" :title="t('header.install_pwa')"
@click="invokeAction('modals.login.toggle')" :icon="IconDownload"
class="rounded hover:bg-primaryDark focus-visible:bg-primaryDark"
@click="installPWA()"
/> />
<HoppButtonPrimary <HoppButtonSecondary
:label="t('header.login')" v-tippy="{ theme: 'tooltip', allowHTML: true }"
@click="invokeAction('modals.login.toggle')" :title="`${
mdAndLarger ? t('support.title') : t('app.options')
} <kbd>?</kbd>`"
:icon="IconLifeBuoy"
class="rounded hover:bg-primaryDark focus-visible:bg-primaryDark"
@click="invokeAction('modals.support.toggle')"
/> />
</div> </div>
<div v-else class="inline-flex items-center space-x-2"> <div class="flex">
<TeamsMemberStack
v-if="
workspace.type === 'team' &&
selectedTeam &&
selectedTeam.teamMembers.length > 1
"
:team-members="selectedTeam.teamMembers"
show-count
class="mx-2"
@handle-click="handleTeamEdit()"
/>
<div <div
class="flex divide-x divide-green-600/25 rounded border border-green-600/25 bg-green-500/[.15] focus-within:divide-green-800/50 focus-within:border-green-800/50 focus-within:bg-green-400/10 hover:divide-green-800/50 hover:border-green-800/50 hover:bg-green-400/10" v-if="currentUser === null"
class="inline-flex items-center space-x-2"
> >
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" :icon="IconUploadCloud"
:title="t('team.invite_tooltip')" :label="t('header.save_workspace')"
:icon="IconUserPlus" class="!focus-visible:text-emerald-600 !hover:text-emerald-600 hidden h-8 border border-emerald-600/25 bg-emerald-500/10 !text-emerald-500 hover:border-emerald-600/20 hover:bg-emerald-600/20 focus-visible:border-emerald-600/20 focus-visible:bg-emerald-600/20 md:flex"
class="py-1.75 !focus-visible:text-green-600 !hover:text-green-600 !text-green-500" @click="invokeAction('modals.login.toggle')"
@click="handleInvite()"
/> />
<HoppButtonSecondary <HoppButtonPrimary
:label="t('header.login')"
class="h-8"
@click="invokeAction('modals.login.toggle')"
/>
</div>
<div v-else class="inline-flex items-center space-x-2">
<TeamsMemberStack
v-if=" v-if="
workspace.type === 'team' && workspace.type === 'team' &&
selectedTeam && selectedTeam &&
selectedTeam?.myRole === 'OWNER' selectedTeam.teamMembers.length > 1
" "
v-tippy="{ theme: 'tooltip' }" :team-members="selectedTeam.teamMembers"
:title="t('team.edit')" show-count
:icon="IconSettings" class="mx-2"
class="py-1.75 !focus-visible:text-green-600 !hover:text-green-600 !text-green-500" @handle-click="handleTeamEdit()"
@click="handleTeamEdit()"
/> />
</div> <div
<tippy class="flex h-8 divide-x divide-emerald-600/25 rounded border border-emerald-600/25 bg-emerald-500/10 focus-within:divide-emerald-600/20 focus-within:border-emerald-600/20 focus-within:bg-emerald-600/20 hover:divide-emerald-600/20 hover:border-emerald-600/20 hover:bg-emerald-600/20"
interactive >
trigger="click" <HoppButtonSecondary
theme="popover" v-tippy="{ theme: 'tooltip' }"
:on-shown="() => accountActions.focus()" :title="t('team.invite_tooltip')"
> :icon="IconUserPlus"
<HoppButtonSecondary class="!focus-visible:text-emerald-600 !hover:text-emerald-600 !text-emerald-500"
v-tippy="{ theme: 'tooltip' }" @click="handleInvite()"
:title="t('workspace.change')" />
:label="mdAndLarger ? workspaceName : ``" <HoppButtonSecondary
:icon="workspace.type === 'personal' ? IconUser : IconUsers" v-if="
class="select-wrapper !focus-visible:text-blue-600 !hover:text-blue-600 rounded border border-blue-600/25 bg-blue-500/[.15] py-[0.4375rem] pr-8 !text-blue-500 hover:border-blue-800/50 hover:bg-blue-400/10 focus-visible:border-blue-800/50 focus-visible:bg-blue-400/10" workspace.type === 'team' &&
/> selectedTeam &&
<template #content="{ hide }"> selectedTeam?.myRole === 'OWNER'
<div "
ref="accountActions" v-tippy="{ theme: 'tooltip' }"
class="flex flex-col focus:outline-none" :title="t('team.edit')"
tabindex="0" :icon="IconSettings"
@keyup.escape="hide()" class="!focus-visible:text-emerald-600 !hover:text-emerald-600 !text-emerald-500"
@click="hide()" @click="handleTeamEdit()"
> />
<WorkspaceSelector /> </div>
</div>
</template>
</tippy>
<span class="px-2">
<tippy <tippy
interactive interactive
trigger="click" trigger="click"
theme="popover" theme="popover"
:on-shown="() => tippyActions.focus()" :on-shown="() => accountActions.focus()"
> >
<HoppSmartPicture <HoppSmartSelectWrapper
v-tippy="{ class="!text-blue-500 !focus-visible:text-blue-600 !hover:text-blue-600"
theme: 'tooltip', >
}" <HoppButtonSecondary
:name="currentUser.uid" v-tippy="{ theme: 'tooltip' }"
:title=" :title="t('workspace.change')"
currentUser.displayName || :label="mdAndLarger ? workspaceName : ``"
currentUser.email || :icon="workspace.type === 'personal' ? IconUser : IconUsers"
t('profile.default_hopp_displayname') class="!focus-visible:text-blue-600 !hover:text-blue-600 h-8 rounded border border-blue-600/25 bg-blue-500/10 pr-8 !text-blue-500 hover:border-blue-600/20 hover:bg-blue-600/20 focus-visible:border-blue-600/20 focus-visible:bg-blue-600/20"
" />
indicator </HoppSmartSelectWrapper>
:indicator-styles="
network.isOnline ? 'bg-green-500' : 'bg-red-500'
"
/>
<template #content="{ hide }"> <template #content="{ hide }">
<div <div
ref="tippyActions" ref="accountActions"
class="flex flex-col focus:outline-none" class="flex flex-col focus:outline-none"
tabindex="0" tabindex="0"
@keyup.p="profile.$el.click()"
@keyup.s="settings.$el.click()"
@keyup.l="logout.$el.click()"
@keyup.escape="hide()" @keyup.escape="hide()"
@click="hide()"
> >
<div class="flex flex-col px-2 text-tiny"> <WorkspaceSelector />
<span class="inline-flex truncate font-semibold">
{{
currentUser.displayName ||
t("profile.default_hopp_displayname")
}}
</span>
<span class="inline-flex truncate text-secondaryLight">
{{ currentUser.email }}
</span>
</div>
<hr />
<HoppSmartItem
ref="profile"
to="/profile"
:icon="IconUser"
:label="t('navigation.profile')"
:shortcut="['P']"
@click="hide()"
/>
<HoppSmartItem
ref="settings"
to="/settings"
:icon="IconSettings"
:label="t('navigation.settings')"
:shortcut="['S']"
@click="hide()"
/>
<FirebaseLogout
ref="logout"
:shortcut="['L']"
@confirm-logout="hide()"
/>
</div> </div>
</template> </template>
</tippy> </tippy>
</span> <span class="px-2">
<tippy
interactive
trigger="click"
theme="popover"
:on-shown="() => tippyActions.focus()"
>
<HoppSmartPicture
v-tippy="{
theme: 'tooltip',
}"
:name="currentUser.uid"
:title="
currentUser.displayName ||
currentUser.email ||
t('profile.default_hopp_displayname')
"
indicator
:indicator-styles="
network.isOnline ? 'bg-green-500' : 'bg-red-500'
"
/>
<template #content="{ hide }">
<div
ref="tippyActions"
class="flex flex-col focus:outline-none"
tabindex="0"
@keyup.p="profile.$el.click()"
@keyup.s="settings.$el.click()"
@keyup.l="logout.$el.click()"
@keyup.escape="hide()"
>
<div class="flex flex-col px-2">
<span class="inline-flex truncate font-semibold">
{{
currentUser.displayName ||
t("profile.default_hopp_displayname")
}}
</span>
<span
class="inline-flex truncate text-secondaryLight text-tiny"
>
{{ currentUser.email }}
</span>
</div>
<hr />
<HoppSmartItem
ref="profile"
to="/profile"
:icon="IconUser"
:label="t('navigation.profile')"
:shortcut="['P']"
@click="hide()"
/>
<HoppSmartItem
ref="settings"
to="/settings"
:icon="IconSettings"
:label="t('navigation.settings')"
:shortcut="['S']"
@click="hide()"
/>
<FirebaseLogout
ref="logout"
:shortcut="['L']"
@confirm-logout="hide()"
/>
</div>
</template>
</tippy>
</span>
</div>
</div> </div>
</div> </div>
</header> </header>
@@ -219,7 +232,6 @@
@invite-team="inviteTeam(editingTeamName, editingTeamID)" @invite-team="inviteTeam(editingTeamName, editingTeamID)"
@refetch-teams="refetchTeams" @refetch-teams="refetchTeams"
/> />
<HoppSmartConfirmModal <HoppSmartConfirmModal
:show="confirmRemove" :show="confirmRemove"
:title="t('confirm.remove_team')" :title="t('confirm.remove_team')"
@@ -279,7 +291,7 @@ const bannerContent = computed(() => banner.content.value?.content)
let bannerID: number | null = null let bannerID: number | null = null
const offlineBanner: BannerContent = { const offlineBanner: BannerContent = {
type: "info", type: "warning",
text: (t) => t("helpers.offline"), text: (t) => t("helpers.offline"),
alternateText: (t) => t("helpers.offline_short"), alternateText: (t) => t("helpers.offline_short"),
score: BANNER_PRIORITY_HIGH, score: BANNER_PRIORITY_HIGH,

View File

@@ -9,8 +9,8 @@
> >
<component <component
:is="entry.icon" :is="entry.icon"
class="svg-icons opacity-50" class="svg-icons opacity-80"
:class="{ 'opacity-100': active }" :class="{ 'opacity-25': active }"
/> />
<template <template
v-if="entry.text.type === 'text' && typeof entry.text.text === 'string'" v-if="entry.text.type === 'text' && typeof entry.text.text === 'string'"
@@ -82,9 +82,9 @@ const props = defineProps<{
const formattedShortcutKeys = computed( const formattedShortcutKeys = computed(
() => () =>
props.entry.meta?.keyboardShortcut?.map((key) => { props.entry.meta?.keyboardShortcut?.map(
return SPECIAL_KEY_CHARS[key] ?? capitalize(key) (key) => SPECIAL_KEY_CHARS[key] ?? capitalize(key)
}) )
) )
const emit = defineEmits<{ const emit = defineEmits<{

View File

@@ -16,7 +16,7 @@
autocomplete="off" autocomplete="off"
name="command" name="command"
:placeholder="`${t('app.type_a_command_search')}`" :placeholder="`${t('app.type_a_command_search')}`"
class="flex flex-1 bg-transparent px-6 py-5 text-base text-secondaryDark" class="flex flex-1 bg-transparent px-6 pt-5 pb-3 text-base text-secondaryDark"
/> />
<HoppSmartSpinner v-if="searchSession?.loading" class="mr-6" /> <HoppSmartSpinner v-if="searchSession?.loading" class="mr-6" />
</div> </div>

View File

@@ -14,14 +14,14 @@
></div> ></div>
<div class="relative flex flex-col"> <div class="relative flex flex-col">
<div <div
class="z-1 pointer-events-none absolute inset-0 bg-accent opacity-0 transition" class="z-[1] pointer-events-none absolute inset-0 bg-accent opacity-0 transition"
:class="{ :class="{
'opacity-25': 'opacity-25':
dragging && notSameDestination && notSameParentDestination, dragging && notSameDestination && notSameParentDestination,
}" }"
></div> ></div>
<div <div
class="z-3 group pointer-events-auto relative flex cursor-pointer items-stretch" class="z-[3] group pointer-events-auto relative flex cursor-pointer items-stretch"
:draggable="!hasNoTeamAccess" :draggable="!hasNoTeamAccess"
@dragstart="dragStart" @dragstart="dragStart"
@drop="handelDrop($event)" @drop="handelDrop($event)"

View File

@@ -78,7 +78,7 @@
v-else-if="step.name === 'TARGET_MY_COLLECTION'" v-else-if="step.name === 'TARGET_MY_COLLECTION'"
class="flex flex-col" class="flex flex-col"
> >
<div class="select-wrapper"> <HoppSmartSelectWrapper>
<select <select
v-model="mySelectedCollectionID" v-model="mySelectedCollectionID"
autocomplete="off" autocomplete="off"
@@ -97,7 +97,7 @@
{{ collection.name }} {{ collection.name }}
</option> </option>
</select> </select>
</div> </HoppSmartSelectWrapper>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -28,8 +28,7 @@
> >
<span <span
class="pointer-events-none flex w-16 items-center justify-center truncate px-2" class="pointer-events-none flex w-16 items-center justify-center truncate px-2"
:class="requestLabelColor" :style="{ color: getMethodLabelColorClassOf(request) }"
:style="{ color: requestLabelColor }"
> >
<component <component
:is="IconCheckCircle" :is="IconCheckCircle"
@@ -277,10 +276,6 @@ const currentReorderingStatus = useReadonlyStream(currentReorderingStatus$, {
parentID: "", parentID: "",
}) })
const requestLabelColor = computed(() =>
getMethodLabelColorClassOf(props.request)
)
watch( watch(
() => props.duplicateLoading, () => props.duplicateLoading,
(val) => { (val) => {

View File

@@ -15,12 +15,12 @@
class="!rounded-none" class="!rounded-none"
:icon="IconPlus" :icon="IconPlus"
:title="t('team.no_access')" :title="t('team.no_access')"
:label="t('add.new')" :label="t('action.new')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-else v-else
:icon="IconPlus" :icon="IconPlus"
:label="t('add.new')" :label="t('action.new')"
class="!rounded-none" class="!rounded-none"
@click="emit('display-modal-add')" @click="emit('display-modal-add')"
/> />

View File

@@ -11,7 +11,7 @@
@dragend="draggingToRoot = false" @dragend="draggingToRoot = false"
> >
<div <div
class="sticky z-10 flex flex-shrink-0 flex-col overflow-x-auto border-b border-dividerLight bg-primary" class="sticky z-10 flex flex-shrink-0 flex-col overflow-x-auto bg-primary border-b border-dividerLight"
:class="{ 'rounded-t': saveRequest }" :class="{ 'rounded-t': saveRequest }"
:style=" :style="
saveRequest ? 'top: calc(-1 * var(--line-height-body))' : 'top: 0' saveRequest ? 'top: calc(-1 * var(--line-height-body))' : 'top: 0'
@@ -22,7 +22,7 @@
v-model="filterTexts" v-model="filterTexts"
type="search" type="search"
autocomplete="off" autocomplete="off"
class="flex h-8 w-full bg-transparent p-4 py-2" class="flex w-full bg-transparent px-4 py-2"
:placeholder="t('action.search')" :placeholder="t('action.search')"
:disabled="collectionsType.type === 'team-collections'" :disabled="collectionsType.type === 'team-collections'"
/> />

View File

@@ -7,7 +7,7 @@
<template #body> <template #body>
<div class="flex flex-1 flex-col space-y-4"> <div class="flex flex-1 flex-col space-y-4">
<div class="ml-2 flex items-center space-x-8"> <div class="ml-2 flex items-center space-x-8">
<label for="name" class="min-w-10 font-semibold">{{ <label for="name" class="min-w-[2.5rem] font-semibold">{{
t("environment.name") t("environment.name")
}}</label> }}</label>
<input <input
@@ -18,7 +18,7 @@
/> />
</div> </div>
<div class="ml-2 flex items-center space-x-8"> <div class="ml-2 flex items-center space-x-8">
<label for="value" class="min-w-10 font-semibold">{{ <label for="value" class="min-w-[2.5rem] font-semibold">{{
t("environment.value") t("environment.value")
}}</label> }}</label>
<input <input
@@ -29,7 +29,7 @@
/> />
</div> </div>
<div class="ml-2 flex items-center space-x-8"> <div class="ml-2 flex items-center space-x-8">
<label for="scope" class="min-w-10 font-semibold"> <label for="scope" class="min-w-[2.5rem] font-semibold">
{{ t("environment.scope") }} {{ t("environment.scope") }}
</label> </label>
<div <div
@@ -39,7 +39,7 @@
</div> </div>
</div> </div>
<div v-if="replaceWithVariable" class="mt-3 flex space-x-2"> <div v-if="replaceWithVariable" class="mt-3 flex space-x-2">
<div class="min-w-18" /> <div class="min-w-[4rem]" />
<HoppSmartCheckbox <HoppSmartCheckbox
:on="replaceWithVariable" :on="replaceWithVariable"
:title="t('environment.replace_with_variable')" :title="t('environment.replace_with_variable')"

View File

@@ -6,10 +6,9 @@
theme="popover" theme="popover"
:on-shown="() => envSelectorActions!.focus()" :on-shown="() => envSelectorActions!.focus()"
> >
<span <HoppSmartSelectWrapper
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="`${t('environment.select')}`" :title="`${t('environment.select')}`"
class="select-wrapper"
> >
<HoppButtonSecondary <HoppButtonSecondary
:icon="IconLayers" :icon="IconLayers"
@@ -22,7 +21,7 @@
" "
class="flex-1 !justify-start rounded-none pr-8" class="flex-1 !justify-start rounded-none pr-8"
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div <div
ref="envSelectorActions" ref="envSelectorActions"
@@ -207,10 +206,14 @@
</div> </div>
<div class="my-2 flex flex-1 flex-col space-y-2 pl-4 pr-2"> <div class="my-2 flex flex-1 flex-col space-y-2 pl-4 pr-2">
<div class="flex flex-1 space-x-4"> <div class="flex flex-1 space-x-4">
<span class="min-w-32 w-1/4 truncate text-tiny font-semibold"> <span
class="min-w-[9rem] w-1/4 truncate text-tiny font-semibold"
>
{{ t("environment.name") }} {{ t("environment.name") }}
</span> </span>
<span class="min-w-32 w-full truncate text-tiny font-semibold"> <span
class="min-w-[9rem] w-full truncate text-tiny font-semibold"
>
{{ t("environment.value") }} {{ t("environment.value") }}
</span> </span>
</div> </div>
@@ -219,10 +222,10 @@
:key="index" :key="index"
class="flex flex-1 space-x-4" class="flex flex-1 space-x-4"
> >
<span class="min-w-32 w-1/4 truncate text-secondaryLight"> <span class="min-w-[9rem] w-1/4 truncate text-secondaryLight">
{{ variable.key }} {{ variable.key }}
</span> </span>
<span class="min-w-32 w-full truncate text-secondaryLight"> <span class="min-w-[9rem] w-full truncate text-secondaryLight">
{{ variable.value }} {{ variable.value }}
</span> </span>
</div> </div>
@@ -258,10 +261,14 @@
</div> </div>
<div v-else class="my-2 flex flex-1 flex-col space-y-2 pl-4 pr-2"> <div v-else class="my-2 flex flex-1 flex-col space-y-2 pl-4 pr-2">
<div class="flex flex-1 space-x-4"> <div class="flex flex-1 space-x-4">
<span class="min-w-32 w-1/4 truncate text-tiny font-semibold"> <span
class="min-w-[9rem] w-1/4 truncate text-tiny font-semibold"
>
{{ t("environment.name") }} {{ t("environment.name") }}
</span> </span>
<span class="min-w-32 w-full truncate text-tiny font-semibold"> <span
class="min-w-[9rem] w-full truncate text-tiny font-semibold"
>
{{ t("environment.value") }} {{ t("environment.value") }}
</span> </span>
</div> </div>
@@ -270,10 +277,10 @@
:key="index" :key="index"
class="flex flex-1 space-x-4" class="flex flex-1 space-x-4"
> >
<span class="min-w-32 w-1/4 truncate text-secondaryLight"> <span class="min-w-[9rem] w-1/4 truncate text-secondaryLight">
{{ variable.key }} {{ variable.key }}
</span> </span>
<span class="min-w-32 w-full truncate text-secondaryLight"> <span class="min-w-[9rem] w-full truncate text-secondaryLight">
{{ variable.value }} {{ variable.value }}
</span> </span>
</div> </div>

View File

@@ -13,12 +13,12 @@
theme="popover" theme="popover"
:on-shown="() => tippyActions.focus()" :on-shown="() => tippyActions.focus()"
> >
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<HoppButtonSecondary <HoppButtonSecondary
class="ml-2 rounded-none pr-8" class="ml-2 rounded-none pr-8"
:label="authName" :label="authName"
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div <div
ref="tippyActions" ref="tippyActions"
@@ -171,7 +171,7 @@
</div> </div>
</div> </div>
<div <div
class="z-9 sticky top-upperTertiaryStickyFold h-full min-w-46 max-w-1/3 flex-shrink-0 overflow-auto overflow-x-auto bg-primary p-4" class="z-[9] sticky top-upperTertiaryStickyFold h-full min-w-[12rem] max-w-1/3 flex-shrink-0 overflow-auto overflow-x-auto bg-primary p-4"
> >
<div class="pb-2 text-secondaryLight"> <div class="pb-2 text-secondaryLight">
{{ t("helpers.authorization") }} {{ t("helpers.authorization") }}

View File

@@ -30,7 +30,7 @@
v-model="graphqlFieldsFilterText" v-model="graphqlFieldsFilterText"
type="search" type="search"
autocomplete="off" autocomplete="off"
class="flex h-8 w-full bg-transparent p-4 py-2" class="flex w-full bg-transparent px-4 py-2"
:placeholder="`${t('action.search')}`" :placeholder="`${t('action.search')}`"
/> />
<div class="flex"> <div class="flex">

View File

@@ -14,7 +14,7 @@
theme="popover" theme="popover"
:on-shown="() => tippyActions!.focus()" :on-shown="() => tippyActions!.focus()"
> >
<span class="truncate px-2 leading-8"> <span class="truncate">
{{ tab.document.request.name }} {{ tab.document.request.name }}
</span> </span>
<template #content="{ hide }"> <template #content="{ hide }">

View File

@@ -9,7 +9,7 @@
v-model="filterText" v-model="filterText"
type="search" type="search"
autocomplete="off" autocomplete="off"
class="flex h-8 w-full bg-transparent p-4 py-2" class="flex w-full bg-transparent px-4 py-2"
:placeholder="`${t('action.search')}`" :placeholder="`${t('action.search')}`"
/> />
<div class="flex"> <div class="flex">

View File

@@ -13,12 +13,12 @@
theme="popover" theme="popover"
:on-shown="() => tippyActions.focus()" :on-shown="() => tippyActions.focus()"
> >
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<HoppButtonSecondary <HoppButtonSecondary
class="ml-2 rounded-none pr-8" class="ml-2 rounded-none pr-8"
:label="authName" :label="authName"
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div <div
ref="tippyActions" ref="tippyActions"
@@ -149,7 +149,7 @@
</div> </div>
</div> </div>
<div <div
class="z-9 sticky top-upperTertiaryStickyFold h-full min-w-46 max-w-1/3 flex-shrink-0 overflow-auto overflow-x-auto bg-primary p-4" class="z-[9] sticky top-upperTertiaryStickyFold h-full min-w-[12rem] max-w-1/3 flex-shrink-0 overflow-auto overflow-x-auto bg-primary p-4"
> >
<div class="pb-2 text-secondaryLight"> <div class="pb-2 text-secondaryLight">
{{ t("helpers.authorization") }} {{ t("helpers.authorization") }}

View File

@@ -13,12 +13,12 @@
theme="popover" theme="popover"
:on-shown="() => tippyActions.focus()" :on-shown="() => tippyActions.focus()"
> >
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<HoppButtonSecondary <HoppButtonSecondary
:label="body.contentType || t('state.none')" :label="body.contentType || t('state.none')"
class="ml-2 rounded-none pr-8" class="ml-2 rounded-none pr-8"
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div <div
ref="tippyActions" ref="tippyActions"

View File

@@ -17,7 +17,7 @@
placement="bottom" placement="bottom"
:on-shown="() => tippyActions.focus()" :on-shown="() => tippyActions.focus()"
> >
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<HoppButtonSecondary <HoppButtonSecondary
:label=" :label="
CodegenDefinitions.find((x) => x.name === codegenType)!.caption CodegenDefinitions.find((x) => x.name === codegenType)!.caption
@@ -25,7 +25,7 @@
outline outline
class="flex-1 pr-8" class="flex-1 pr-8"
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div class="flex flex-col space-y-2"> <div class="flex flex-col space-y-2">
<div class="sticky top-0 z-10 flex-shrink-0 overflow-x-auto"> <div class="sticky top-0 z-10 flex-shrink-0 overflow-x-auto">

View File

@@ -34,7 +34,7 @@
<div ref="preRequestEditor" class="h-full"></div> <div ref="preRequestEditor" class="h-full"></div>
</div> </div>
<div <div
class="z-9 sticky top-upperTertiaryStickyFold h-full min-w-46 max-w-1/3 flex-shrink-0 overflow-auto overflow-x-auto bg-primary p-4" class="z-[9] sticky top-upperTertiaryStickyFold h-full min-w-[12rem] max-w-1/3 flex-shrink-0 overflow-auto overflow-x-auto bg-primary p-4"
> >
<div class="pb-2 text-secondaryLight"> <div class="pb-2 text-secondaryLight">
{{ t("helpers.pre_request_script") }} {{ t("helpers.pre_request_script") }}

View File

@@ -3,7 +3,7 @@
class="sticky top-0 z-20 flex-none flex-shrink-0 bg-primary p-4 sm:flex sm:flex-shrink-0 sm:space-x-2" class="sticky top-0 z-20 flex-none flex-shrink-0 bg-primary p-4 sm:flex sm:flex-shrink-0 sm:space-x-2"
> >
<div <div
class="min-w-52 flex flex-1 whitespace-nowrap rounded border border-divider" class="min-w-[12rem] flex flex-1 whitespace-nowrap rounded border border-divider"
> >
<div class="relative flex"> <div class="relative flex">
<label for="method"> <label for="method">
@@ -13,7 +13,7 @@
theme="popover" theme="popover"
:on-shown="() => methodTippyActions.focus()" :on-shown="() => methodTippyActions.focus()"
> >
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<input <input
id="method" id="method"
class="flex w-26 cursor-pointer rounded-l bg-primaryLight px-4 py-2 font-semibold text-secondaryDark transition" class="flex w-26 cursor-pointer rounded-l bg-primaryLight px-4 py-2 font-semibold text-secondaryDark transition"
@@ -22,7 +22,7 @@
:placeholder="`${t('request.method')}`" :placeholder="`${t('request.method')}`"
@input="onSelectMethod($event)" @input="onSelectMethod($event)"
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div <div
ref="methodTippyActions" ref="methodTippyActions"
@@ -34,6 +34,9 @@
v-for="(method, index) in methods" v-for="(method, index) in methods"
:key="`method-${index}`" :key="`method-${index}`"
:label="method" :label="method"
:style="{
color: getMethodLabelColor(method),
}"
@click=" @click="
() => { () => {
updateMethod(method) updateMethod(method)
@@ -67,7 +70,7 @@
'action.send' 'action.send'
)} <kbd>${getSpecialKey()}</kbd><kbd>↩</kbd>`" )} <kbd>${getSpecialKey()}</kbd><kbd>↩</kbd>`"
:label="`${!loading ? t('action.send') : t('action.cancel')}`" :label="`${!loading ? t('action.send') : t('action.cancel')}`"
class="min-w-20 flex-1 rounded-r-none" class="min-w-[5rem] flex-1 rounded-r-none"
@click="!loading ? newSendRequest() : cancelRequest()" @click="!loading ? newSendRequest() : cancelRequest()"
/> />
<span class="flex"> <span class="flex">
@@ -259,6 +262,7 @@ import { InterceptorService } from "~/services/interceptor.service"
import { HoppTab } from "~/services/tab" import { HoppTab } from "~/services/tab"
import { HoppRESTDocument } from "~/helpers/rest/document" import { HoppRESTDocument } from "~/helpers/rest/document"
import { RESTTabService } from "~/services/tab/rest" import { RESTTabService } from "~/services/tab/rest"
import { getMethodLabelColor } from "~/helpers/rest/labelColoring"
const t = useI18n() const t = useI18n()
const interceptorService = useService(InterceptorService) const interceptorService = useService(InterceptorService)
@@ -270,8 +274,8 @@ const methods = [
"PATCH", "PATCH",
"DELETE", "DELETE",
"HEAD", "HEAD",
"CONNECT",
"OPTIONS", "OPTIONS",
"CONNECT",
"TRACE", "TRACE",
"CUSTOM", "CUSTOM",
] ]

View File

@@ -8,12 +8,11 @@
@click.middle="emit('close-tab')" @click.middle="emit('close-tab')"
> >
<span <span
class="text-tiny font-semibold" class="text-tiny font-semibold mr-2"
:style="{ color: getMethodLabelColorClassOf(tab.document.request) }" :style="{ color: getMethodLabelColorClassOf(tab.document.request) }"
> >
{{ tab.document.request.method }} {{ tab.document.request.method }}
</span> </span>
<tippy <tippy
ref="options" ref="options"
trigger="manual" trigger="manual"
@@ -21,7 +20,7 @@
theme="popover" theme="popover"
:on-shown="() => tippyActions!.focus()" :on-shown="() => tippyActions!.focus()"
> >
<span class="truncate px-2 leading-8"> <span class="truncate">
{{ tab.document.request.name }} {{ tab.document.request.name }}
</span> </span>
<template #content="{ hide }"> <template #content="{ hide }">

View File

@@ -34,7 +34,7 @@
<div ref="testScriptEditor" class="h-full"></div> <div ref="testScriptEditor" class="h-full"></div>
</div> </div>
<div <div
class="z-9 sticky top-upperTertiaryStickyFold h-full min-w-46 max-w-1/3 flex-shrink-0 overflow-auto overflow-x-auto bg-primary p-4" class="z-[9] sticky top-upperTertiaryStickyFold h-full min-w-[12rem] max-w-1/3 flex-shrink-0 overflow-auto overflow-x-auto bg-primary p-4"
> >
<div class="pb-2 text-secondaryLight"> <div class="pb-2 text-secondaryLight">
{{ t("helpers.post_request_tests") }} {{ t("helpers.post_request_tests") }}

View File

@@ -16,12 +16,12 @@
theme="popover" theme="popover"
:on-shown="() => authTippyActions.focus()" :on-shown="() => authTippyActions.focus()"
> >
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<HoppButtonSecondary <HoppButtonSecondary
:label="auth.addTo || t('state.none')" :label="auth.addTo || t('state.none')"
class="ml-2 rounded-none pr-8" class="ml-2 rounded-none pr-8"
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div <div
ref="authTippyActions" ref="authTippyActions"

View File

@@ -33,12 +33,12 @@
theme="popover" theme="popover"
:on-shown="() => tippyActions.focus()" :on-shown="() => tippyActions.focus()"
> >
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<HoppButtonSecondary <HoppButtonSecondary
:label="contentType || t('state.none').toLowerCase()" :label="contentType || t('state.none').toLowerCase()"
class="ml-2 rounded-none pr-8" class="ml-2 rounded-none pr-8"
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div <div
ref="tippyActions" ref="tippyActions"
@@ -279,6 +279,7 @@ defineActionHandler("request.send-cancel", sendMessage)
:deep(.cm-panels) { :deep(.cm-panels) {
@apply top-upperSecondaryStickyFold #{!important}; @apply top-upperSecondaryStickyFold #{!important};
} }
.eventFeildShown :deep(.cm-panels), .eventFeildShown :deep(.cm-panels),
.cmResponsePrimaryStickyFold :deep(.cm-panels) { .cmResponsePrimaryStickyFold :deep(.cm-panels) {
@apply top-upperTertiaryStickyFold #{!important}; @apply top-upperTertiaryStickyFold #{!important};

View File

@@ -62,12 +62,12 @@
{{ t("mqtt.lw_qos") }} {{ t("mqtt.lw_qos") }}
</label> </label>
<tippy interactive trigger="click" theme="popover"> <tippy interactive trigger="click" theme="popover">
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<HoppButtonSecondary <HoppButtonSecondary
class="ml-2 rounded-none pr-8" class="ml-2 rounded-none pr-8"
:label="`${config.lwQos}`" :label="`${config.lwQos}`"
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div class="flex flex-col" role="menu"> <div class="flex flex-col" role="menu">
<HoppSmartItem <HoppSmartItem

View File

@@ -35,8 +35,8 @@
autoScrollEnabled ? t('action.turn_off') : t('action.turn_on') autoScrollEnabled ? t('action.turn_off') : t('action.turn_on')
}`" }`"
:icon="IconChevronsDown" :icon="IconChevronsDown"
:class="toggleAutoscrollColor" :color="autoScrollEnabled ? 'green' : 'red'"
@click="toggleAutoscroll()" @click="autoScrollEnabled = !autoScrollEnabled"
/> />
</div> </div>
</div> </div>
@@ -60,7 +60,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, PropType, computed, watch, Ref } from "vue" import { ref, PropType, watch, Ref } from "vue"
import IconTrash from "~icons/lucide/trash" import IconTrash from "~icons/lucide/trash"
import IconArrowUp from "~icons/lucide/arrow-up" import IconArrowUp from "~icons/lucide/arrow-up"
import IconArrowDown from "~icons/lucide/arrow-down" import IconArrowDown from "~icons/lucide/arrow-down"
@@ -123,12 +123,4 @@ watch(
}, 200), }, 200),
{ flush: "post" } { flush: "post" }
) )
const toggleAutoscroll = () => {
autoScrollEnabled.value = !autoScrollEnabled.value
}
const toggleAutoscrollColor = computed(() =>
autoScrollEnabled.value ? "text-green-500" : "text-red-500"
)
</script> </script>

View File

@@ -12,7 +12,7 @@
</div> </div>
<div <div
v-if="entry.ts !== undefined" v-if="entry.ts !== undefined"
class="w-34 hidden items-center px-1 sm:inline-flex" class="w-36 hidden items-center px-1 sm:inline-flex"
> >
<span <span
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"

View File

@@ -9,9 +9,9 @@
{{ t("mqtt.qos") }} {{ t("mqtt.qos") }}
</label> </label>
<tippy interactive trigger="click" theme="popover"> <tippy interactive trigger="click" theme="popover">
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<HoppButtonSecondary class="pr-8" :label="`${QoS}`" /> <HoppButtonSecondary class="pr-8" :label="`${QoS}`" />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div class="flex flex-col" role="menu"> <div class="flex flex-col" role="menu">
<HoppSmartItem <HoppSmartItem

View File

@@ -6,7 +6,7 @@
theme="popover" theme="popover"
:on-shown="() => tippyActions.focus()" :on-shown="() => tippyActions.focus()"
> >
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('settings.choose_language')" :title="t('settings.choose_language')"
@@ -15,7 +15,7 @@
outline outline
:label="currentLocale.name" :label="currentLocale.name"
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div class="flex flex-col space-y-2"> <div class="flex flex-col space-y-2">
<HoppSmartInput <HoppSmartInput

View File

@@ -19,7 +19,7 @@
class="svg-icons opacity-75" class="svg-icons opacity-75"
:class="label ? (reverse ? 'ml-4' : 'mr-4') : ''" :class="label ? (reverse ? 'ml-4' : 'mr-4') : ''"
/> />
<div class="max-w-54 truncate"> <div class="max-w-[16rem] truncate">
{{ label }} {{ label }}
</div> </div>
</HoppSmartLink> </HoppSmartLink>

View File

@@ -25,7 +25,7 @@
class="svg-icons" class="svg-icons"
:class="label ? 'mr-4 opacity-75' : ''" :class="label ? 'mr-4 opacity-75' : ''"
/> />
<div class="max-w-54 truncate"> <div class="max-w-[16rem] truncate">
{{ label }} {{ label }}
</div> </div>
</HoppSmartLink> </HoppSmartLink>

View File

@@ -75,7 +75,7 @@
theme="popover" theme="popover"
:on-shown="() => tippyActions![index].focus()" :on-shown="() => tippyActions![index].focus()"
> >
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<input <input
class="flex flex-1 cursor-pointer bg-transparent px-4 py-2" class="flex flex-1 cursor-pointer bg-transparent px-4 py-2"
:placeholder="`${t('team.permissions')}`" :placeholder="`${t('team.permissions')}`"
@@ -83,7 +83,7 @@
:value="member.role" :value="member.role"
readonly readonly
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div <div
ref="tippyActions" ref="tippyActions"

View File

@@ -169,7 +169,7 @@
theme="popover" theme="popover"
:on-shown="() => tippyActions![index].focus()" :on-shown="() => tippyActions![index].focus()"
> >
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<input <input
class="flex flex-1 cursor-pointer bg-transparent px-4 py-2" class="flex flex-1 cursor-pointer bg-transparent px-4 py-2"
:placeholder="`${t('team.permissions')}`" :placeholder="`${t('team.permissions')}`"
@@ -177,7 +177,7 @@
:value="invitee.value" :value="invitee.value"
readonly readonly
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div <div
ref="tippyActions" ref="tippyActions"
@@ -272,7 +272,7 @@
<ul class="mt-4 space-y-4"> <ul class="mt-4 space-y-4">
<li class="flex"> <li class="flex">
<span <span
class="max-w-16 w-1/4 truncate font-semibold uppercase text-secondaryDark" class="max-w-[4rem] w-1/4 truncate font-semibold uppercase text-secondaryDark"
> >
{{ t("profile.owner") }} {{ t("profile.owner") }}
</span> </span>
@@ -282,7 +282,7 @@
</li> </li>
<li class="flex"> <li class="flex">
<span <span
class="max-w-16 w-1/4 truncate font-semibold uppercase text-secondaryDark" class="max-w-[4rem] w-1/4 truncate font-semibold uppercase text-secondaryDark"
> >
{{ t("profile.editor") }} {{ t("profile.editor") }}
</span> </span>
@@ -292,7 +292,7 @@
</li> </li>
<li class="flex"> <li class="flex">
<span <span
class="max-w-16 w-1/4 truncate font-semibold uppercase text-secondaryDark" class="max-w-[4rem] w-1/4 truncate font-semibold uppercase text-secondaryDark"
> >
{{ t("profile.viewer") }} {{ t("profile.viewer") }}
</span> </span>

View File

@@ -14,19 +14,19 @@ export default function (responseStatus) {
if (responseStatus >= 300 && responseStatus < 400) if (responseStatus >= 300 && responseStatus < 400)
return { return {
name: "redirection", name: "redirection",
className: "redir-response", className: "redirect-response",
} }
if (responseStatus >= 400 && responseStatus < 500) if (responseStatus >= 400 && responseStatus < 500)
return { return {
name: "client error", name: "client error",
className: "cl-error-response", className: "critical-error-response",
} }
if (responseStatus >= 500 && responseStatus < 600) if (responseStatus >= 500 && responseStatus < 600)
return { return {
name: "server error", name: "server error",
className: "sv-error-response", className: "server-error-response",
} }
// this object is a catch-all for when no other objects match and should always be last // this object is a catch-all for when no other objects match and should always be last

View File

@@ -4,11 +4,14 @@ import * as RR from "fp-ts/ReadonlyRecord"
import { HoppRESTRequest } from "@hoppscotch/data" import { HoppRESTRequest } from "@hoppscotch/data"
export const REQUEST_METHOD_LABEL_COLORS = { export const REQUEST_METHOD_LABEL_COLORS = {
get: "var(--success-color)", get: "var(--method-get-color)",
post: "var(--warning-color)", post: "var(--method-post-color)",
put: "var(--blue-color)", put: "var(--method-put-color)",
delete: "var(--cl-error-color)", patch: "var(--method-patch-color)",
default: "#6b7280", delete: "var(--method-delete-color)",
head: "var(--method-head-color)",
options: "var(--method-options-color)",
default: "var(--method-default-color)",
} as const } as const
/** /**
@@ -23,3 +26,11 @@ export function getMethodLabelColorClassOf(request: HoppRESTRequest) {
O.getOrElseW(() => REQUEST_METHOD_LABEL_COLORS.default) O.getOrElseW(() => REQUEST_METHOD_LABEL_COLORS.default)
) )
} }
export function getMethodLabelColor(method: string) {
return pipe(
REQUEST_METHOD_LABEL_COLORS,
RR.lookup(method.toLowerCase()),
O.getOrElseW(() => REQUEST_METHOD_LABEL_COLORS.default)
)
}

View File

@@ -98,7 +98,7 @@
filled filled
outline outline
:label="t('action.save')" :label="t('action.save')"
class="min-w-16 ml-2" class="min-w-[4rem] ml-2"
type="submit" type="submit"
:loading="updatingDisplayName" :loading="updatingDisplayName"
@click="updateDisplayName" @click="updateDisplayName"
@@ -121,7 +121,7 @@
filled filled
outline outline
:label="t('action.save')" :label="t('action.save')"
class="min-w-16 ml-2" class="min-w-[4rem] ml-2"
type="submit" type="submit"
:loading="updatingEmailAddress" :loading="updatingEmailAddress"
@click="updateEmailAddress" @click="updateEmailAddress"

View File

@@ -2,7 +2,7 @@
<HoppSmartTabs <HoppSmartTabs
v-model="currentTab" v-model="currentTab"
styles="sticky overflow-x-auto flex-shrink-0 bg-primary top-0 z-10" styles="sticky overflow-x-auto flex-shrink-0 bg-primary top-0 z-10"
content-styles="h-[calc(100%-var(--sidebar-primary-sticky-fold)-1px)] !flex" content-styles="!h-[calc(100%-var(--sidebar-primary-sticky-fold)-1px)] !flex"
> >
<HoppSmartTab <HoppSmartTab
v-for="{ target, title } in REALTIME_NAVIGATION" v-for="{ target, title } in REALTIME_NAVIGATION"

View File

@@ -13,7 +13,7 @@
theme="popover" theme="popover"
:on-shown="() => tippyActions.focus()" :on-shown="() => tippyActions.focus()"
> >
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<input <input
id="client-version" id="client-version"
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
@@ -26,7 +26,7 @@
connectionState === 'CONNECTING' connectionState === 'CONNECTING'
" "
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div <div
ref="tippyActions" ref="tippyActions"
@@ -129,12 +129,12 @@
theme="popover" theme="popover"
:on-shown="() => authTippyActions.focus()" :on-shown="() => authTippyActions.focus()"
> >
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<HoppButtonSecondary <HoppButtonSecondary
class="ml-2 rounded-none pr-8" class="ml-2 rounded-none pr-8"
:label="authType" :label="authType"
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div <div
ref="authTippyActions" ref="authTippyActions"
@@ -216,7 +216,7 @@
</div> </div>
</div> </div>
<div <div
class="z-9 sticky top-upperTertiaryStickyFold h-full min-w-46 max-w-1/3 flex-shrink-0 overflow-auto overflow-x-auto bg-primary p-4" class="z-[9] sticky top-upperTertiaryStickyFold h-full min-w-[12rem] max-w-1/3 flex-shrink-0 overflow-auto overflow-x-auto bg-primary p-4"
> >
<div class="p-2"> <div class="p-2">
<div class="pb-2 text-secondaryLight"> <div class="pb-2 text-secondaryLight">

View File

@@ -7,4 +7,26 @@ export default {
"../hoppscotch-ui/src/**/*.{vue,html}", "../hoppscotch-ui/src/**/*.{vue,html}",
], ],
presets: [preset], presets: [preset],
theme: {
extend: {
inset: {
upperPrimaryStickyFold: "var(--upper-primary-sticky-fold)",
upperSecondaryStickyFold: "var(--upper-secondary-sticky-fold)",
upperTertiaryStickyFold: "var(--upper-tertiary-sticky-fold)",
upperFourthStickyFold: "var(--upper-fourth-sticky-fold)",
upperMobilePrimaryStickyFold: "var(--upper-mobile-primary-sticky-fold)",
upperMobileSecondaryStickyFold:
"var(--upper-mobile-secondary-sticky-fold)",
upperMobileStickyFold: "var(--upper-mobile-sticky-fold)",
upperMobileTertiaryStickyFold:
"var(--upper-mobile-tertiary-sticky-fold)",
lowerPrimaryStickyFold: "var(--lower-primary-sticky-fold)",
lowerSecondaryStickyFold: "var(--lower-secondary-sticky-fold)",
lowerTertiaryStickyFold: "var(--lower-tertiary-sticky-fold)",
lowerFourthStickyFold: "var(--lower-fourth-sticky-fold)",
sidebarPrimaryStickyFold: "var(--sidebar-primary-sticky-fold)",
sidebarSecondaryStickyFold: "var(--line-height-body)",
},
},
},
} satisfies Config } satisfies Config

View File

@@ -1,4 +1,3 @@
module.exports = { module.exports = {
semi: false, semi: false,
plugins: [require("prettier-plugin-tailwindcss")], };
}

View File

@@ -5,18 +5,17 @@
@mixin base-theme { @mixin base-theme {
--font-sans: 'Inter Variable', sans-serif; --font-sans: 'Inter Variable', sans-serif;
--font-icon: 'Material Symbols Rounded Variable';
--font-mono: 'Roboto Mono Variable', monospace; --font-mono: 'Roboto Mono Variable', monospace;
--font-size-body: 0.75rem; --font-size-body: 0.75rem;
--font-size-tiny: 0.688rem; --font-size-tiny: 0.625rem;
--line-height-body: 1rem; --line-height-body: 1rem;
--upper-primary-sticky-fold: 4.125rem; --upper-primary-sticky-fold: 4rem;
--upper-secondary-sticky-fold: 6.188rem; --upper-secondary-sticky-fold: 6.188rem;
--upper-tertiary-sticky-fold: 8.25rem; --upper-tertiary-sticky-fold: 8.25rem;
--upper-fourth-sticky-fold: 10.2rem; --upper-fourth-sticky-fold: 10.2rem;
--upper-mobile-primary-sticky-fold: 6.625rem; --upper-mobile-primary-sticky-fold: 6.75rem;
--upper-mobile-secondary-sticky-fold: 8.688rem; --upper-mobile-secondary-sticky-fold: 8.813rem;
--upper-mobile-sticky-fold: 10.75rem; --upper-mobile-sticky-fold: 10.875rem;
--upper-mobile-tertiary-sticky-fold: 8.25rem; --upper-mobile-tertiary-sticky-fold: 8.25rem;
--lower-primary-sticky-fold: 3rem; --lower-primary-sticky-fold: 3rem;
--lower-secondary-sticky-fold: 5.063rem; --lower-secondary-sticky-fold: 5.063rem;
@@ -95,14 +94,6 @@
@apply antialiased; @apply antialiased;
accent-color: var(--accent-color); accent-color: var(--accent-color);
font-variant-ligatures: common-ligatures; font-variant-ligatures: common-ligatures;
// Colors
--info-color: #ec4899;
--success-color: #10b981;
--blue-color: #3b82f6;
--warning-color: #f59e0b;
--cl-error-color: #ef4444;
--sv-error-color: #dc2626;
} }
::-webkit-scrollbar-track { ::-webkit-scrollbar-track {
@@ -131,7 +122,7 @@ input::placeholder,
textarea::placeholder, textarea::placeholder,
.cm-placeholder { .cm-placeholder {
@apply text-secondary; @apply text-secondary;
@apply opacity-50; @apply opacity-50 #{!important};
} }
input, input,
@@ -150,7 +141,7 @@ body {
@apply font-medium; @apply font-medium;
@apply select-none; @apply select-none;
@apply overflow-x-hidden; @apply overflow-x-hidden;
@apply leading-body; @apply leading-body #{!important};
animation: fade 300ms forwards; animation: fade 300ms forwards;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none; -webkit-touch-callout: none;
@@ -248,7 +239,7 @@ a {
@apply font-semibold; @apply font-semibold;
@apply px-2 py-1; @apply px-2 py-1;
@apply truncate; @apply truncate;
@apply leading-normal; @apply leading-body;
@apply items-center; @apply items-center;
kbd { kbd {
@@ -295,7 +286,7 @@ a {
@apply overflow-y-auto; @apply overflow-y-auto;
@apply text-body text-secondary; @apply text-body text-secondary;
@apply p-2; @apply p-2;
@apply leading-normal; @apply leading-body;
@apply focus:outline-none; @apply focus:outline-none;
scroll-behavior: smooth; scroll-behavior: smooth;
@@ -327,7 +318,7 @@ a {
hr { hr {
@apply border-b border-dividerLight; @apply border-b border-dividerLight;
@apply my-2; @apply my-2 #{!important};
} }
.heading { .heading {
@@ -416,44 +407,28 @@ pre.ace_editor {
} }
} }
.select-wrapper {
@apply flex flex-1;
@apply relative;
@apply after:absolute;
@apply after:flex;
@apply after:inset-y-0;
@apply after:items-center;
@apply after:justify-center;
@apply after:pointer-events-none;
@apply after:font-icon;
@apply after:text-current;
@apply after:right-3;
@apply after:content-["\e5cf"];
@apply after:text-lg;
}
.info-response { .info-response {
color: var(--info-color); color: var(--status-info-color);
} }
.success-response { .success-response {
color: var(--success-color); color: var(--status-success-color);
} }
.redir-response { .redirect-response {
color: var(--warning-color); color: var(--status-redirect-color);
} }
.cl-error-response { .critical-error-response {
color: var(--cl-error-color); color: var(--status-critical-error-color);
} }
.sv-error-response { .server-error-response {
color: var(--sv-error-color); color: var(--status-server-error-color);
} }
.missing-data-response { .missing-data-response {
@apply text-secondaryLight; color: var(--status-missing-data-color);
} }
.toasted-container { .toasted-container {
@@ -603,12 +578,12 @@ pre.ace_editor {
@apply inline-flex; @apply inline-flex;
@apply font-sans; @apply font-sans;
@apply text-tiny; @apply text-tiny;
@apply bg-divider; @apply bg-dividerLight;
@apply rounded; @apply rounded;
@apply ml-2; @apply ml-2;
@apply px-1; @apply px-1;
@apply min-w-5; @apply min-w-[1.25rem];
@apply min-h-5; @apply min-h-[1.25rem];
@apply items-center; @apply items-center;
@apply justify-center; @apply justify-center;
@apply border border-dividerDark; @apply border border-dividerDark;

View File

@@ -2,7 +2,7 @@
<div> <div>
<button <button
@click="open = true" @click="open = true"
class="inline-flex items-center bg-emerald-700 h-8 ml-3 pl-2.5 pr-2 rounded-md shadow border-gray-800 border border-gray-200 leading-none py-0 hover:bg-emerald-700 focus:outline-none focus:bg-emerald-800" class="inline-flex items-center bg-emerald-700 h-8 ml-3 pl-2.5 pr-2 rounded-md shadow border-gray-800 border border-gray-200 py-0 hover:bg-emerald-700 focus:outline-none focus:bg-emerald-800"
> >
Invite User Invite User
</button> </button>

View File

@@ -41,7 +41,7 @@
theme="popover" theme="popover"
:on-shown="() => tippyActions![index].focus()" :on-shown="() => tippyActions![index].focus()"
> >
<span class="select-wrapper"> <HoppSmartSelectWrapper>
<input <input
class="flex flex-1 px-4 py-2 bg-transparent cursor-pointer" class="flex flex-1 px-4 py-2 bg-transparent cursor-pointer"
placeholder="Permissions" placeholder="Permissions"
@@ -49,7 +49,7 @@
:value="member.value" :value="member.value"
readonly readonly
/> />
</span> </HoppSmartSelectWrapper>
<template #content="{ hide }"> <template #content="{ hide }">
<div <div
ref="tippyActions" ref="tippyActions"
@@ -140,7 +140,7 @@
<ul class="mt-4 space-y-4"> <ul class="mt-4 space-y-4">
<li class="flex"> <li class="flex">
<span <span
class="w-1/4 font-semibold uppercase truncate text-secondaryDark max-w-16" class="w-1/4 font-semibold uppercase truncate text-secondaryDark max-w-[4rem]"
> >
Owner Owner
</span> </span>
@@ -151,7 +151,7 @@
</li> </li>
<li class="flex"> <li class="flex">
<span <span
class="w-1/4 font-semibold uppercase truncate text-secondaryDark max-w-16" class="w-1/4 font-semibold uppercase truncate text-secondaryDark max-w-[4rem]"
> >
Editor Editor
</span> </span>
@@ -161,7 +161,7 @@
</li> </li>
<li class="flex"> <li class="flex">
<span <span
class="w-1/4 font-semibold uppercase truncate text-secondaryDark max-w-16" class="w-1/4 font-semibold uppercase truncate text-secondaryDark max-w-[4rem]"
> >
Viewer Viewer
</span> </span>

View File

@@ -37,13 +37,13 @@
class="text-secondaryDark hover:bg-divider hover:cursor-pointer rounded-xl" class="text-secondaryDark hover:bg-divider hover:cursor-pointer rounded-xl"
@click="goToTeamDetails(team.id)" @click="goToTeamDetails(team.id)"
> >
<td class="flex py-4 px-7 max-w-50"> <td class="flex py-4 px-7 max-w-[16rem]">
<span class="truncate"> <span class="truncate">
{{ team.id }} {{ team.id }}
</span> </span>
</td> </td>
<td class="py-4 px-7 min-w-80"> <td class="py-4 px-7 min-w-[20rem]">
<span <span
class="flex items-center truncate" class="flex items-center truncate"
:class="{ truncate: team.name }" :class="{ truncate: team.name }"

View File

@@ -49,7 +49,7 @@
class="text-secondaryDark hover:bg-divider hover:cursor-pointer rounded-xl" class="text-secondaryDark hover:bg-divider hover:cursor-pointer rounded-xl"
@click="goToUserDetails(user.uid)" @click="goToUserDetails(user.uid)"
> >
<td class="py-2 px-7 max-w-30 truncate"> <td class="py-2 px-7 max-w-[8rem] truncate">
{{ user.uid }} {{ user.uid }}
</td> </td>

View File

@@ -1,4 +1,3 @@
module.exports = { module.exports = {
semi: false, semi: false,
plugins: ["prettier-plugin-tailwindcss"],
} }

View File

@@ -5,18 +5,17 @@
@mixin base-theme { @mixin base-theme {
--font-sans: "Inter Variable", sans-serif; --font-sans: "Inter Variable", sans-serif;
--font-icon: "Material Symbols Rounded Variable";
--font-mono: "Roboto Mono Variable", monospace; --font-mono: "Roboto Mono Variable", monospace;
--font-size-body: 0.75rem; --font-size-body: 0.75rem;
--font-size-tiny: 0.688rem; --font-size-tiny: 0.625rem;
--line-height-body: 1rem; --line-height-body: 1rem;
--upper-primary-sticky-fold: 4.125rem; --upper-primary-sticky-fold: 4rem;
--upper-secondary-sticky-fold: 6.188rem; --upper-secondary-sticky-fold: 6.188rem;
--upper-tertiary-sticky-fold: 8.25rem; --upper-tertiary-sticky-fold: 8.25rem;
--upper-fourth-sticky-fold: 10.2rem; --upper-fourth-sticky-fold: 10.2rem;
--upper-mobile-primary-sticky-fold: 6.625rem; --upper-mobile-primary-sticky-fold: 6.75rem;
--upper-mobile-secondary-sticky-fold: 8.688rem; --upper-mobile-secondary-sticky-fold: 8.813rem;
--upper-mobile-sticky-fold: 10.75rem; --upper-mobile-sticky-fold: 10.875rem;
--upper-mobile-tertiary-sticky-fold: 8.25rem; --upper-mobile-tertiary-sticky-fold: 8.25rem;
--lower-primary-sticky-fold: 3rem; --lower-primary-sticky-fold: 3rem;
--lower-secondary-sticky-fold: 5.063rem; --lower-secondary-sticky-fold: 5.063rem;
@@ -78,23 +77,13 @@
} }
:root { :root {
@include base-theme;
@include base-theme; @include dark-theme;
@include dark-theme; @include green-theme;
@include green-theme;
@apply antialiased; @apply antialiased;
accent-color: var(--accent-color); accent-color: var(--accent-color);
font-variant-ligatures: common-ligatures; font-variant-ligatures: common-ligatures;
// Colors
--info-color: #ec4899;
--success-color: #10b981;
--blue-color: #3b82f6;
--warning-color: #f59e0b;
--cl-error-color: #ef4444;
--sv-error-color: #dc2626;
} }
::-webkit-scrollbar-track { ::-webkit-scrollbar-track {
@@ -123,7 +112,7 @@ input::placeholder,
textarea::placeholder, textarea::placeholder,
.cm-placeholder { .cm-placeholder {
@apply text-secondary; @apply text-secondary;
@apply opacity-50; @apply opacity-50 #{!important};
} }
input, input,
@@ -142,7 +131,7 @@ body {
@apply font-medium; @apply font-medium;
@apply select-none; @apply select-none;
@apply overflow-x-hidden; @apply overflow-x-hidden;
@apply leading-body; @apply leading-body #{!important};
animation: fade 300ms forwards; animation: fade 300ms forwards;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none; -webkit-touch-callout: none;
@@ -240,7 +229,7 @@ a {
@apply font-semibold; @apply font-semibold;
@apply px-2 py-1; @apply px-2 py-1;
@apply truncate; @apply truncate;
@apply leading-normal; @apply leading-body;
@apply items-center; @apply items-center;
kbd { kbd {
@@ -287,7 +276,7 @@ a {
@apply overflow-y-auto; @apply overflow-y-auto;
@apply text-body text-secondary; @apply text-body text-secondary;
@apply p-2; @apply p-2;
@apply leading-normal; @apply leading-body;
@apply focus:outline-none; @apply focus:outline-none;
scroll-behavior: smooth; scroll-behavior: smooth;
@@ -319,7 +308,7 @@ a {
hr { hr {
@apply border-b border-dividerLight; @apply border-b border-dividerLight;
@apply my-2; @apply my-2 #{!important};
} }
.heading { .heading {
@@ -408,44 +397,28 @@ pre.ace_editor {
} }
} }
.select-wrapper {
@apply flex flex-1;
@apply relative;
@apply after:absolute;
@apply after:flex;
@apply after:inset-y-0;
@apply after:items-center;
@apply after:justify-center;
@apply after:pointer-events-none;
@apply after:font-icon;
@apply after:text-current;
@apply after:right-3;
@apply after:content-["\e5cf"];
@apply after:text-lg;
}
.info-response { .info-response {
color: var(--info-color); color: var(--status-info-color);
} }
.success-response { .success-response {
color: var(--success-color); color: var(--status-success-color);
} }
.redir-response { .redirect-response {
color: var(--warning-color); color: var(--status-redirect-color);
} }
.cl-error-response { .critical-error-response {
color: var(--cl-error-color); color: var(--status-critical-error-color);
} }
.sv-error-response { .server-error-response {
color: var(--sv-error-color); color: var(--status-server-error-color);
} }
.missing-data-response { .missing-data-response {
@apply text-secondaryLight; color: var(--status-missing-data-color);
} }
.toasted-container { .toasted-container {
@@ -595,12 +568,12 @@ pre.ace_editor {
@apply inline-flex; @apply inline-flex;
@apply font-sans; @apply font-sans;
@apply text-tiny; @apply text-tiny;
@apply bg-divider; @apply bg-dividerLight;
@apply rounded; @apply rounded;
@apply ml-2; @apply ml-2;
@apply px-1; @apply px-1;
@apply min-w-5; @apply min-w-[1.25rem];
@apply min-h-5; @apply min-h-[1.25rem];
@apply items-center; @apply items-center;
@apply justify-center; @apply justify-center;
@apply border border-dividerDark; @apply border border-dividerDark;

View File

@@ -40,7 +40,7 @@
label ? (reverse ? 'ml-2' : 'mr-2') : '', label ? (reverse ? 'ml-2' : 'mr-2') : '',
]" ]"
/> />
<div class="max-w-54 truncate"> <div class="max-w-[16rem] truncate">
{{ label }} {{ label }}
</div> </div>
<div v-if="shortcut.length" class="<sm:hidden"> <div v-if="shortcut.length" class="<sm:hidden">

View File

@@ -41,7 +41,7 @@
label ? (reverse ? 'ml-2' : 'mr-2') : '', label ? (reverse ? 'ml-2' : 'mr-2') : '',
]" ]"
/> />
<div class="truncate max-w-54"> <div class="truncate max-w-[16rem]">
{{ label }} {{ label }}
</div> </div>
<div v-if="shortcut.length" class="<sm:hidden"> <div v-if="shortcut.length" class="<sm:hidden">

View File

@@ -6,51 +6,62 @@
@click="emit('change')" @click="emit('change')"
> >
<input <input
id="checkbox" :id="checkboxID"
type="checkbox" type="checkbox"
name="checkbox" :name="name"
class="checkbox" class="checkbox"
:checked="on" :checked="on"
@change="emit('change')" @change="emit('change')"
/> />
<label <label
for="checkbox" :for="checkboxID"
class="pl-0 font-semibold truncate align-middle cursor-pointer" class="pl-0 font-semibold truncate align-middle cursor-pointer"
:class="{
'before:mr-2': labelSlot.default
}"
> >
<slot></slot> <slot></slot>
</label> </label>
</div> </div>
</template> </template>
<script setup lang="ts"> <script lang="ts">
import { useSlots } from 'vue'; /*
This checkboxIDCounter is tracked in the global scope in order to ensure that each checkbox has a unique ID.
When we use this component multiple times on the same page, we need to ensure that each checkbox has a unique ID.
This is because the label's for attribute needs to match the checkbox's id attribute.
That's why we use a global counter that increments each time we use this component.
*/
let checkboxIDCounter = 564275
</script>
<script setup lang="ts">
// Unique ID for checkbox
const checkboxID = `checkbox-${checkboxIDCounter++}`
defineProps({ defineProps({
on: { on: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
name: {
type: String,
default: "checkbox",
},
}) })
const emit = defineEmits<{ const emit = defineEmits<{
(e: "change"): void (e: "change"): void
}>() }>()
// used to check if the default slot is used and add a margin to the label if exists
const labelSlot = useSlots()
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.checkbox[type="checkbox"] { .checkbox[type="checkbox"] {
@apply relative;
@apply appearance-none; @apply appearance-none;
@apply hidden; @apply hidden;
& + label { & + label {
@apply inline-flex items-center justify-center; @apply inline-flex items-center justify-center;
@apply cursor-pointer; @apply cursor-pointer;
@apply relative;
&::before { &::before {
@apply border-2 border-divider; @apply border-2 border-divider;
@@ -62,9 +73,22 @@ const labelSlot = useSlots()
@apply text-transparent; @apply text-transparent;
@apply h-4; @apply h-4;
@apply w-4; @apply w-4;
@apply font-icon; @apply mr-2;
@apply transition; @apply transition;
@apply content-["\e5ca"]; content: "";
}
&::after {
content: "";
border: solid;
border-width: 0 1.9px 1.9px 0;
height: 0.6rem;
width: 0.3rem;
left: 0.35rem;
position: absolute;
top: 2px;
transform: rotate(45deg);
opacity: 0;
} }
} }
@@ -73,5 +97,10 @@ const labelSlot = useSlots()
@apply border-accent; @apply border-accent;
@apply text-accentContrast; @apply text-accentContrast;
} }
&:checked + label::after {
@apply text-accentContrast;
opacity: 1;
}
} }
</style> </style>

View File

@@ -1,12 +1,23 @@
<template> <template>
<div class="relative flex flex-col space-y-2 overflow-hidden" :class="expand ? 'h-full' : 'max-h-32'"> <div
class="relative flex flex-col space-y-2 overflow-hidden"
:class="expand ? 'h-full' : 'max-h-32'"
>
<slot name="body"></slot> <slot name="body"></slot>
<div class="sticky inset-x-0 bottom-0 flex items-center justify-center flex-shrink-0 overflow-x-auto"> <div
<HoppButtonSecondary :icon="expand ? IconChevronUp : IconChevronDown" :label=" class="sticky inset-x-0 bottom-0 flex items-center justify-center flex-shrink-0 overflow-x-auto"
expand >
? less ?? t?.('action.less') ?? 'Less' <HoppButtonSecondary
: more ?? t?.('action.more') ?? 'More' :icon="expand ? IconChevronUp : IconChevronDown"
" filled rounded @click="expand = !expand" /> :label="
expand
? less ?? t?.('action.less') ?? 'Less'
: more ?? t?.('action.more') ?? 'More'
"
filled
rounded
@click="expand = !expand"
/>
</div> </div>
</div> </div>
</template> </template>

View File

@@ -3,7 +3,7 @@
class="inline-flex items-center space-x-1 justify-center rounded px-2 bg-primaryDark" class="inline-flex items-center space-x-1 justify-center rounded px-2 bg-primaryDark"
> >
<IconLucideFile class="opacity-75 svg-icons" /> <IconLucideFile class="opacity-75 svg-icons" />
<span class="truncate max-w-54"><slot></slot></span> <span class="truncate max-w-[16rem]"><slot></slot></span>
</span> </span>
</template> </template>

View File

@@ -1,5 +1,8 @@
<template> <template>
<HoppSmartLink :to="to" :exact="exact" :blank="blank" <HoppSmartLink
:to="to"
:exact="exact"
:blank="blank"
class="inline-flex items-center flex-shrink-0 px-4 py-2 rounded transition hover:bg-primaryDark hover:text-secondaryDark focus:outline-none focus-visible:bg-primaryDark focus-visible:text-secondaryDark" class="inline-flex items-center flex-shrink-0 px-4 py-2 rounded transition hover:bg-primaryDark hover:text-secondaryDark focus:outline-none focus-visible:bg-primaryDark focus-visible:text-secondaryDark"
:class="[ :class="[
{ 'opacity-75 cursor-not-allowed': disabled }, { 'opacity-75 cursor-not-allowed': disabled },
@@ -10,16 +13,32 @@
'border border-divider hover:border-dividerDark focus-visible:border-dividerDark': 'border border-divider hover:border-dividerDark focus-visible:border-dividerDark':
outline, outline,
}, },
]" :disabled="disabled" :tabindex="loading ? '-1' : '0'" role="menuitem"> ]"
<span v-if="!loading" class="inline-flex items-center" :class="{ 'self-start': !!infoIcon }"> :disabled="disabled"
<component :is="icon" v-if="icon" class="opacity-75 svg-icons" :class="[ :tabindex="loading ? '-1' : '0'"
label ? (reverse ? 'ml-4' : 'mr-4') : '', role="menuitem"
{ 'text-accent': active }, >
]" /> <span
v-if="!loading"
class="inline-flex items-center"
:class="{ 'self-start': !!infoIcon }"
>
<component
:is="icon"
v-if="icon"
class="opacity-75 svg-icons"
:class="[
label ? (reverse ? 'ml-4' : 'mr-4') : '',
{ 'text-accent': active },
]"
/>
</span> </span>
<HoppSmartSpinner v-else class="mr-4 text-secondaryDark" /> <HoppSmartSpinner v-else class="mr-4 text-secondaryDark" />
<div class="inline-flex items-start flex-1 truncate" :class="{ 'flex-col': description }"> <div
<div class="font-semibold truncate max-w-54"> class="inline-flex items-start flex-1 truncate"
:class="{ 'flex-col': description }"
>
<div class="font-semibold truncate max-w-[16rem]">
{{ label }} {{ label }}
</div> </div>
<p v-if="description" class="my-2 text-left text-secondaryLight"> <p v-if="description" class="my-2 text-left text-secondaryLight">
@@ -33,7 +52,11 @@
:class="{ 'text-accent': activeInfoIcon }" :class="{ 'text-accent': activeInfoIcon }"
/> />
<div v-if="shortcut.length" class="ml-4 <sm:hidden font-medium"> <div v-if="shortcut.length" class="ml-4 <sm:hidden font-medium">
<kbd v-for="(key, index) in shortcut" :key="`key-${index}`" class="-mr-2 shortcut-key"> <kbd
v-for="(key, index) in shortcut"
:key="`key-${index}`"
class="-mr-2 shortcut-key"
>
{{ key }} {{ key }}
</kbd> </kbd>
</div> </div>
@@ -48,7 +71,7 @@ import { defineComponent } from "vue"
export default defineComponent({ export default defineComponent({
components: { components: {
HoppSmartLink, HoppSmartLink,
HoppSmartSpinner HoppSmartSpinner,
}, },
props: { props: {
to: { to: {

View File

@@ -44,7 +44,6 @@
</h3> </h3>
<span class="flex items-center"> <span class="flex items-center">
<slot name="actions"></slot> <slot name="actions"></slot>
<kbd class="shortcut-key mr-2">ESC</kbd>
<HoppButtonSecondary <HoppButtonSecondary
v-if="dimissible" v-if="dimissible"
v-tippy="{ theme: 'tooltip', delay: [500, 20] }" v-tippy="{ theme: 'tooltip', delay: [500, 20] }"

View File

@@ -19,7 +19,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { Avatar } from "@boringer-avatars/vue3"; import { Avatar } from "@boringer-avatars/vue3"
withDefaults( withDefaults(
defineProps<{ defineProps<{
@@ -32,7 +32,7 @@ withDefaults(
name: "", name: "",
indicator: false, indicator: false,
indicatorStyles: "bg-green-500", indicatorStyles: "bg-green-500",
size: 24, size: 22,
} }
) )
</script> </script>

View File

@@ -0,0 +1,30 @@
<template>
<div class="select-wrapper">
<span class="down-icon text-xs">
<IconChevronDown />
</span>
<slot />
</div>
</template>
<script setup lang="ts">
import IconChevronDown from '~icons/lucide/chevron-down'
</script>
<style scoped lang="scss">
.select-wrapper {
@apply flex flex-1;
@apply relative;
}
.down-icon {
@apply absolute;
@apply flex;
@apply inset-y-0;
@apply items-center;
@apply justify-center;
@apply pointer-events-none;
@apply text-current;
@apply right-3;
}
</style>

View File

@@ -26,7 +26,7 @@
v-for="cellHeading in headings" v-for="cellHeading in headings"
:key="cellHeading.key" :key="cellHeading.key"
@click="!cellHeading.preventClick && onRowClicked(rowData)" @click="!cellHeading.preventClick && onRowClicked(rowData)"
class="max-w-40 pl-6 py-1" class="max-w-[10rem] pl-6 py-1"
> >
<!-- Dynamic column slot --> <!-- Dynamic column slot -->
<slot :name="cellHeading.key" :item="rowData"> <slot :name="cellHeading.key" :item="rowData">

View File

@@ -1,7 +1,7 @@
<template> <template>
<div <div
class="flex h-full flex-1 flex-nowrap" class="flex h-full flex-1 flex-nowrap"
:class="{ 'h-auto flex-col': !vertical }" :class="{ '!h-auto !flex-col': !vertical }"
> >
<div <div
class="tabs relative border-dividerLight" class="tabs relative border-dividerLight"
@@ -221,8 +221,8 @@ const selectTab = (id: string) => {
@apply items-center; @apply items-center;
@apply justify-center; @apply justify-center;
@apply px-1; @apply px-1;
@apply leading-[15px]; @apply min-w-[1rem];
@apply min-w-4; @apply h-4;
@apply ml-2; @apply ml-2;
@apply text-[8px]; @apply text-[8px];
@apply border border-divider; @apply border border-divider;

View File

@@ -24,7 +24,7 @@
<button <button
:key="`removable-tab-${tabID}`" :key="`removable-tab-${tabID}`"
:id="`removable-tab-${tabID}`" :id="`removable-tab-${tabID}`"
class="px-2 tab group" class="tab group"
:class="[{ active: modelValue === tabID }]" :class="[{ active: modelValue === tabID }]"
:aria-label="tabMeta.label || ''" :aria-label="tabMeta.label || ''"
role="button" role="button"
@@ -81,11 +81,11 @@
</draggable> </draggable>
</div> </div>
<div <div
class="sticky right-0 flex items-center justify-center flex-shrink-0 overflow-x-auto z-14" class="sticky right-0 flex items-center justify-center flex-shrink-0 overflow-x-auto z-20"
> >
<span <span
v-if="canAddNewTab" v-if="canAddNewTab"
class="flex items-center justify-center h-full px-3 bg-primaryLight z-8" class="flex items-center justify-center h-full px-3 bg-primaryLight z-[8]"
> >
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
@@ -382,9 +382,10 @@ watch(
.tab { .tab {
@apply relative; @apply relative;
@apply flex; @apply flex;
@apply py-2; @apply p-2;
@apply font-semibold; @apply font-semibold;
@apply w-46; @apply w-46;
@apply h-12;
@apply transition; @apply transition;
@apply flex-1; @apply flex-1;
@apply items-center; @apply items-center;

View File

@@ -24,3 +24,4 @@ export { default as HoppSmartPicture } from "./Picture.vue"
export { default as HoppSmartPlaceholder } from "./Placeholder.vue" export { default as HoppSmartPlaceholder } from "./Placeholder.vue"
export { default as HoppSmartTree } from "./Tree.vue" export { default as HoppSmartTree } from "./Tree.vue"
export { default as HoppSmartTreeBranch } from "./TreeBranch.vue" export { default as HoppSmartTreeBranch } from "./TreeBranch.vue"
export { default as HoppSmartSelectWrapper } from "./SelectWrapper.vue"

View File

@@ -29,7 +29,7 @@
<td <td
v-for="cellHeading in headings" v-for="cellHeading in headings"
:key="cellHeading.key" :key="cellHeading.key"
class="max-w-40 pl-6 py-1" class="max-w-[10rem] pl-6 py-1"
> >
{{ item[cellHeading.key] ?? "-" }} {{ item[cellHeading.key] ?? "-" }}
</td> </td>

View File

@@ -1,5 +1,5 @@
import { Config } from "tailwindcss"; import { Config } from "tailwindcss"
import { theme } from 'tailwindcss/defaultConfig' import { theme } from "tailwindcss/defaultConfig"
export default { export default {
content: [], content: [],
@@ -8,22 +8,6 @@ export default {
center: true, center: true,
}, },
extend: { extend: {
inset: {
upperPrimaryStickyFold: "var(--upper-primary-sticky-fold)",
upperSecondaryStickyFold: "var(--upper-secondary-sticky-fold)",
upperTertiaryStickyFold: "var(--upper-tertiary-sticky-fold)",
upperFourthStickyFold: "var(--upper-fourth-sticky-fold)",
upperMobilePrimaryStickyFold: "var(--upper-mobile-primary-sticky-fold)",
upperMobileSecondaryStickyFold: "var(--upper-mobile-secondary-sticky-fold)",
upperMobileStickyFold: "var(--upper-mobile-sticky-fold)",
upperMobileTertiaryStickyFold: "var(--upper-mobile-tertiary-sticky-fold)",
lowerPrimaryStickyFold: "var(--lower-primary-sticky-fold)",
lowerSecondaryStickyFold: "var(--lower-secondary-sticky-fold)",
lowerTertiaryStickyFold: "var(--lower-tertiary-sticky-fold)",
lowerFourthStickyFold: "var(--lower-fourth-sticky-fold)",
sidebarPrimaryStickyFold: "var(--sidebar-primary-sticky-fold)",
sidebarSecondaryStickyFold: "var(--line-height-body)",
},
colors: { colors: {
primary: "var(--primary-color)", primary: "var(--primary-color)",
primaryLight: "var(--primary-light-color)", primaryLight: "var(--primary-light-color)",
@@ -39,9 +23,9 @@ export default {
divider: "var(--divider-color)", divider: "var(--divider-color)",
dividerLight: "var(--divider-light-color)", dividerLight: "var(--divider-light-color)",
dividerDark: "var(--divider-dark-color)", dividerDark: "var(--divider-dark-color)",
info: "var(--info-color)", bannerInfo: "var(--banner-info-color)",
warning: "var(--warning-color)", bannerWarning: "var(--banner-warning-color)",
error: "var(--error-color)", bannerError: "var(--banner-error-color)",
tooltip: "var(--tooltip-color)", tooltip: "var(--tooltip-color)",
popover: "var(--popover-color)", popover: "var(--popover-color)",
gradientFrom: "var(--gradient-from-color)", gradientFrom: "var(--gradient-from-color)",
@@ -66,7 +50,6 @@ export default {
fontFamily: { fontFamily: {
sans: "var(--font-sans)", sans: "var(--font-sans)",
mono: "var(--font-mono)", mono: "var(--font-mono)",
icon: "var(--font-icon)",
}, },
fontSize: { fontSize: {
tiny: "var(--font-size-tiny)", tiny: "var(--font-size-tiny)",
@@ -98,9 +81,9 @@ export default {
46: "11.5rem", 46: "11.5rem",
}, },
maxWidth: { maxWidth: {
'1/2': '50%', "1/2": "50%",
'1/3': '33%', "1/3": "33%",
'3/4': '75%', "3/4": "75%",
46: "11.5rem", 46: "11.5rem",
}, },
maxHeight: { maxHeight: {
@@ -112,15 +95,9 @@ export default {
backgroundOpacity: { backgroundOpacity: {
15: "0.15", 15: "0.15",
}, },
}, screens: {
screens: { "<sm": { max: "640px" },
sm: "639px", },
"<2xl": { max: "1536px" },
"<xl": { max: "1280px" },
"<lg": { max: "1024px" },
"<md": { max: "768px" },
"<sm": { max: "640px" },
...theme?.screens,
}, },
}, },
} satisfies Config } satisfies Config