Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
ac378790
Commit
ac378790
authored
Jan 16, 2019
by
Dominik Prokop
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP Basics of named color picker
parent
7ad430a6
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
358 additions
and
9 deletions
+358
-9
packages/grafana-ui/src/components/ColorPicker/ColorPicker.story.tsx
+7
-5
packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx
+3
-0
packages/grafana-ui/src/components/ColorPicker/NamedColorsPicker.story.tsx
+68
-0
packages/grafana-ui/src/components/ColorPicker/NamedColorsPicker.tsx
+121
-0
packages/grafana-ui/src/utils/colors.ts
+0
-1
packages/grafana-ui/src/utils/colorsPalette.test.ts
+31
-0
packages/grafana-ui/src/utils/colorsPalette.ts
+125
-0
yarn.lock
+3
-3
No files found.
packages/grafana-ui/src/components/ColorPicker/ColorPicker.story.tsx
View file @
ac378790
import
React
,
{
FunctionComponent
}
from
'react'
;
import
{
storiesOf
}
from
'@storybook/react'
;
import
{
ColorPicker
}
from
'@grafana/ui'
;
import
{
withInfo
}
from
'@storybook/addon-info'
;
import
{
ColorPickerPopover
}
from
'./ColorPickerPopover'
;
const
CenteredStory
:
FunctionComponent
<
{}
>
=
({
children
})
=>
{
return
(
...
...
@@ -20,6 +19,9 @@ const CenteredStory: FunctionComponent<{}> = ({ children }) => {
storiesOf
(
'UI/ColorPicker'
,
module
)
.
addDecorator
(
story
=>
<
CenteredStory
>
{
story
()
}
</
CenteredStory
>)
.
add
(
'default'
,
withInfo
({
inline
:
true
})(()
=>
{
return
<
ColorPicker
color=
"#ff0000"
onChange=
{
()
=>
{}
}
/>;
}));
// .add('Color picker popover', () => {
// return <ColorPickerPopover color="#ff0000" onColorSelect={() => {}} />;
// })
.
add
(
'Named colors swatch'
,
()
=>
{
return
<
ColorPickerPopover
color=
"#ff0000"
onColorSelect=
{
()
=>
{}
}
/>;
});
packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx
View file @
ac378790
...
...
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
import
ReactDOM
from
'react-dom'
;
import
Drop
from
'tether-drop'
;
import
{
ColorPickerPopover
}
from
'./ColorPickerPopover'
;
import
{
Color
}
from
'../../utils/colorsPalette'
;
interface
Props
{
/**
...
...
@@ -9,6 +10,7 @@ interface Props {
*
* @default " "
**/
name
?:
Color
;
color
:
string
;
onChange
:
(
c
:
string
)
=>
void
;
}
...
...
@@ -55,6 +57,7 @@ export class ColorPicker extends Component<Props, any> {
};
render
()
{
return
(
<
div
className=
"sp-replacer sp-light"
onClick=
{
this
.
openColorPicker
}
ref=
{
element
=>
(
this
.
pickerElem
=
element
)
}
>
<
div
className=
"sp-preview"
>
...
...
packages/grafana-ui/src/components/ColorPicker/NamedColorsPicker.story.tsx
0 → 100644
View file @
ac378790
import
React
,
{
FunctionComponent
}
from
'react'
;
import
{
storiesOf
}
from
'@storybook/react'
;
import
NamedColorsPicker
from
'./NamedColorsPicker'
;
import
{
Color
,
getColorName
}
from
'@grafana/ui/src/utils/colorsPalette'
;
const
CenteredStory
:
FunctionComponent
<
{}
>
=
({
children
})
=>
{
return
(
<
div
style=
{
{
height
:
'100vh '
,
display
:
'flex'
,
alignItems
:
'center'
,
justifyContent
:
'center'
,
}
}
>
{
children
}
</
div
>
);
};
interface
StateHolderProps
<
T
>
{
initialState
:
T
;
children
:
(
currentState
:
T
,
updateState
:
(
nextState
:
T
)
=>
void
)
=>
JSX
.
Element
;
}
class
UseState
<
T
>
extends
React
.
Component
<
StateHolderProps
<
T
>
,
{
value
:
T
}
>
{
constructor
(
props
:
StateHolderProps
<
T
>
)
{
super
(
props
)
this
.
state
=
{
value
:
props
.
initialState
}
}
handleStateUpdate
=
(
nextState
:
T
)
=>
{
this
.
setState
({
value
:
nextState
})
}
render
()
{
return
this
.
props
.
children
(
this
.
state
.
value
,
this
.
handleStateUpdate
)
}
}
storiesOf
(
'UI/ColorPicker'
,
module
)
.
addDecorator
(
story
=>
<
CenteredStory
>
{
story
()
}
</
CenteredStory
>)
.
add
(
'Named colors swatch - support for named colors'
,
()
=>
{
return
(
<
UseState
initialState=
"green"
>
{
(
selectedColor
,
updateSelectedColor
)
=>
{
return
(
<
NamedColorsPicker
selectedColor=
{
selectedColor
as
Color
}
onChange=
{
(
color
)
=>
{
updateSelectedColor
(
color
.
name
);}
}
/>
)
}
}
</
UseState
>);
})
.
add
(
'Named colors swatch - support for hex values'
,
()
=>
{
return
(
<
UseState
initialState=
"#00ff00"
>
{
(
selectedColor
,
updateSelectedColor
)
=>
{
return
(
<
NamedColorsPicker
selectedColor=
{
getColorName
(
selectedColor
)
}
onChange=
{
(
color
)
=>
updateSelectedColor
(
color
.
variants
.
dark
)
}
/>
)
}
}
</
UseState
>);
});
packages/grafana-ui/src/components/ColorPicker/NamedColorsPicker.tsx
0 → 100644
View file @
ac378790
import
React
,
{
FunctionComponent
}
from
'react'
;
import
{
find
,
upperFirst
}
from
'lodash'
;
import
{
Color
,
ColorsPalete
,
ColorDefinition
}
from
'../../utils/colorsPalette'
;
type
ColorChangeHandler
=
(
color
:
ColorDefinition
)
=>
void
;
enum
ColorSwatchVariant
{
Small
=
'small'
,
Large
=
'large'
,
}
interface
ColorSwatchProps
extends
React
.
DOMAttributes
<
HTMLDivElement
>
{
color
:
ColorDefinition
;
variant
?:
ColorSwatchVariant
;
isSelected
?:
boolean
;
}
const
ColorSwatch
:
FunctionComponent
<
ColorSwatchProps
>
=
({
color
,
variant
=
ColorSwatchVariant
.
Small
,
isSelected
,
...
otherProps
})
=>
{
const
isSmall
=
variant
===
ColorSwatchVariant
.
Small
;
const
swatchSize
=
isSmall
?
'16px'
:
'32px'
;
const
swatchStyles
=
{
width
:
swatchSize
,
height
:
swatchSize
,
borderRadius
:
'50%'
,
background
:
`
${
color
.
variants
.
dark
}
`
,
marginRight
:
isSmall
?
'0px'
:
'8px'
,
boxShadow
:
isSelected
?
`inset 0 0 0 2px
${
color
.
variants
.
dark
}
, inset 0 0 0 4px white`
:
'none'
,
cursor
:
isSelected
?
'default'
:
'pointer'
};
return
(
<
div
style=
{
{
display
:
'flex'
,
alignItems
:
'center'
,
}
}
{
...
otherProps
}
>
<
div
style=
{
swatchStyles
}
/>
{
variant
===
ColorSwatchVariant
.
Large
&&
<
span
>
{
upperFirst
(
color
.
hue
)
}
</
span
>
}
</
div
>
);
};
const
ColorsGroup
=
({
colors
,
selectedColor
,
onColorSelect
,
}:
{
colors
:
ColorDefinition
[];
selectedColor
?:
Color
;
onColorSelect
:
ColorChangeHandler
})
=>
{
const
primaryColor
=
find
(
colors
,
color
=>
!!
color
.
isPrimary
);
return
(
<
div
style=
{
{
display
:
'flex'
,
flexDirection
:
'column'
}
}
>
{
primaryColor
&&
(
<
ColorSwatch
isSelected=
{
primaryColor
.
name
===
selectedColor
}
variant=
{
ColorSwatchVariant
.
Large
}
color=
{
primaryColor
}
onClick=
{
()
=>
onColorSelect
(
primaryColor
)
}
/>
)
}
<
div
style=
{
{
display
:
'flex'
,
marginTop
:
'8px'
,
}
}
>
{
colors
.
map
(
color
=>
!
color
.
isPrimary
&&
(
<
div
style=
{
{
marginRight
:
'4px'
}
}
>
<
ColorSwatch
isSelected=
{
color
.
name
===
selectedColor
}
color=
{
color
}
onClick=
{
()
=>
onColorSelect
(
color
)
}
/>
</
div
>
))
}
</
div
>
</
div
>
);
};
interface
NamedColorsPickerProps
{
selectedColor
?:
Color
;
onChange
:
ColorChangeHandler
;
}
const
NamedColorsPicker
=
({
selectedColor
,
onChange
}:
NamedColorsPickerProps
)
=>
{
const
swatches
:
JSX
.
Element
[]
=
[];
ColorsPalete
.
forEach
((
colors
,
hue
)
=>
{
swatches
.
push
(
<>
<
ColorsGroup
selectedColor=
{
selectedColor
}
colors=
{
colors
}
onColorSelect=
{
onChange
}
/>
</>
);
});
return
(
<
div
style=
{
{
display
:
'grid'
,
gridTemplateColumns
:
'repeat(3, 1fr)'
,
gridRowGap
:
'32px'
,
gridColumnGap
:
'32px'
,
}
}
>
{
swatches
}
</
div
>
);
};
export
default
NamedColorsPicker
;
packages/grafana-ui/src/utils/colors.ts
View file @
ac378790
...
...
@@ -9,7 +9,6 @@ export const ALERTING_COLOR = 'rgba(237, 46, 24, 1)';
export
const
NO_DATA_COLOR
=
'rgba(150, 150, 150, 1)'
;
export
const
PENDING_COLOR
=
'rgba(247, 149, 32, 1)'
;
export
const
REGION_FILL_ALPHA
=
0.09
;
export
const
colors
=
[
'#7EB26D'
,
// 0: pale green
'#EAB839'
,
// 1: mustard
...
...
packages/grafana-ui/src/utils/colorsPalette.test.ts
0 → 100644
View file @
ac378790
import
{
getColorName
,
getColorDefinition
,
ColorsPalete
,
buildColorDefinition
}
from
'./colorsPalette'
;
describe
(
'colors'
,
()
=>
{
const
FakeBlue
=
buildColorDefinition
(
'blue'
,
'blue'
,
[
'#0000ff'
,
'#00000ee'
]);
beforeAll
(()
=>
{
ColorsPalete
.
set
(
'blue'
,
[
FakeBlue
])
});
describe
(
'getColorDefinition'
,
()
=>
{
it
(
'returns undefined for unknown hex'
,
()
=>
{
expect
(
getColorDefinition
(
'#ff0000'
)).
toBeUndefined
();
});
it
(
'returns definition for known hex'
,
()
=>
{
expect
(
getColorDefinition
(
FakeBlue
.
variants
.
light
)).
toEqual
(
FakeBlue
);
expect
(
getColorDefinition
(
FakeBlue
.
variants
.
dark
)).
toEqual
(
FakeBlue
);
});
});
describe
(
'getColorName'
,
()
=>
{
it
(
'returns undefined for unknown hex'
,
()
=>
{
expect
(
getColorName
(
'#ff0000'
)).
toBeUndefined
();
});
it
(
'returns name for known hex'
,
()
=>
{
expect
(
getColorName
(
FakeBlue
.
variants
.
light
)).
toEqual
(
FakeBlue
.
name
);
expect
(
getColorName
(
FakeBlue
.
variants
.
dark
)).
toEqual
(
FakeBlue
.
name
);
});
});
});
packages/grafana-ui/src/utils/colorsPalette.ts
0 → 100644
View file @
ac378790
import
{
flatten
,
some
,
values
}
from
'lodash'
;
type
Hue
=
'green'
|
'yellow'
|
'red'
|
'blue'
|
'orange'
|
'purple'
;
export
type
Color
=
|
'green'
|
'dark-green'
|
'semi-dark-green'
|
'light-green'
|
'super-light-green'
|
'yellow'
|
'dark-yellow'
|
'semi-dark-yellow'
|
'light-yellow'
|
'super-light-yellow'
|
'red'
|
'dark-red'
|
'semi-dark-red'
|
'light-red'
|
'super-light-red'
|
'blue'
|
'dark-blue'
|
'semi-dark-blue'
|
'light-blue'
|
'super-light-blue'
|
'orange'
|
'dark-orange'
|
'semi-dark-orange'
|
'light-orange'
|
'super-light-orange'
|
'purple'
|
'dark-purple'
|
'semi-dark-purple'
|
'light-purple'
|
'super-light-purple'
;
type
ThemeVariants
=
{
dark
:
string
;
light
:
string
;
};
export
type
ColorDefinition
=
{
hue
:
Hue
;
isPrimary
?:
boolean
;
name
:
Color
;
variants
:
ThemeVariants
;
};
export
const
ColorsPalete
=
new
Map
<
Hue
,
ColorDefinition
[]
>
();
export
const
buildColorDefinition
=
(
hue
:
Hue
,
name
:
Color
,
[
light
,
dark
]:
string
[],
isPrimary
?:
boolean
):
ColorDefinition
=>
({
hue
,
name
,
variants
:
{
light
,
dark
,
},
isPrimary
:
!!
isPrimary
,
});
export
const
BasicGreen
=
buildColorDefinition
(
'green'
,
'green'
,
[
'#53A642'
,
'#53A642'
],
true
);
export
const
DarkGreen
=
buildColorDefinition
(
'green'
,
'dark-green'
,
[
'#106100'
,
'#106100'
]);
export
const
SemiDarkGreen
=
buildColorDefinition
(
'green'
,
'semi-dark-green'
,
[
'#388729'
,
'#388729'
]);
export
const
LightGreen
=
buildColorDefinition
(
'green'
,
'light-green'
,
[
'#72C462'
,
'#72C462'
]);
export
const
SuperLightGreen
=
buildColorDefinition
(
'green'
,
'super-light-green'
,
[
'#99E68A'
,
'#99E68A'
]);
export
const
BasicYellow
=
buildColorDefinition
(
'yellow'
,
'yellow'
,
[
'#F2CA00'
,
'#F2CA00'
],
true
);
export
const
DarkYellow
=
buildColorDefinition
(
'yellow'
,
'dark-yellow'
,
[
'#A68A00'
,
'#A68A00'
]);
export
const
SemiDarkYellow
=
buildColorDefinition
(
'yellow'
,
'semi-dark-yellow'
,
[
'#CCAA00'
,
'#CCAA00'
]);
export
const
LightYellow
=
buildColorDefinition
(
'yellow'
,
'light-yellow'
,
[
'#F7D636'
,
'#F7D636'
]);
export
const
SuperLightYellow
=
buildColorDefinition
(
'yellow'
,
'super-light-yellow'
,
[
'#FFEB8A'
,
'#FFEB8A'
]);
export
const
BasicRed
=
buildColorDefinition
(
'red'
,
'red'
,
[
'#F94462'
,
'#F94462'
],
true
);
export
const
DarkRed
=
buildColorDefinition
(
'red'
,
'dark-red'
,
[
'#B3001D'
,
'#B3001D'
]);
export
const
SemiDarkRed
=
buildColorDefinition
(
'red'
,
'semi-dark-red'
,
[
'#D93651'
,
'#D93651'
]);
export
const
LightRed
=
buildColorDefinition
(
'red'
,
'light-red'
,
[
'#F07387'
,
'#F07387'
]);
export
const
SuperLightRed
=
buildColorDefinition
(
'red'
,
'super-light-red'
,
[
'#E6A1AC'
,
'#E6A1AC'
]);
export
const
BasicBlue
=
buildColorDefinition
(
'blue'
,
'blue'
,
[
'#408BFF'
,
'#408BFF'
],
true
);
export
const
DarkBlue
=
buildColorDefinition
(
'blue'
,
'dark-blue'
,
[
'#2155A6'
,
'#2155A6'
]);
export
const
SemiDarkBlue
=
buildColorDefinition
(
'blue'
,
'semi-dark-blue'
,
[
'#3471CF'
,
'#3471CF'
]);
export
const
LightBlue
=
buildColorDefinition
(
'blue'
,
'light-blue'
,
[
'#7DAEFA'
,
'#7DAEFA'
]);
export
const
SuperLightBlue
=
buildColorDefinition
(
'blue'
,
'super-light-blue'
,
[
'#B8D0F5'
,
'#B8D0F5'
]);
export
const
BasicOrange
=
buildColorDefinition
(
'orange'
,
'orange'
,
[
'#FA6400'
,
'#FA6400'
],
true
);
export
const
DarkOrange
=
buildColorDefinition
(
'orange'
,
'dark-orange'
,
[
'#963C00'
,
'#963C00'
]);
export
const
SemiDarkOrange
=
buildColorDefinition
(
'orange'
,
'semi-dark-orange'
,
[
'#ED4B00'
,
'#ED4B00'
]);
export
const
LightOrange
=
buildColorDefinition
(
'orange'
,
'light-orange'
,
[
'#FC934C'
,
'#FC934C'
]);
export
const
SuperLightOrange
=
buildColorDefinition
(
'orange'
,
'super-light-orange'
,
[
'#FFC299'
,
'#FFC299'
]);
export
const
BasicPurple
=
buildColorDefinition
(
'purple'
,
'purple'
,
[
'#BC67E6'
,
'#BC67E6'
],
true
);
export
const
DarkPurple
=
buildColorDefinition
(
'purple'
,
'dark-purple'
,
[
'#701F99'
,
'#701F99'
]);
export
const
SemiDarkPurple
=
buildColorDefinition
(
'purple'
,
'semi-dark-purple'
,
[
'#9E43CC'
,
'#9E43CC'
]);
export
const
LightPurple
=
buildColorDefinition
(
'purple'
,
'light-purple'
,
[
'#D19AED'
,
'#D19AED'
]);
export
const
SuperLightPurple
=
buildColorDefinition
(
'purple'
,
'super-light-purple'
,
[
'#E6CEF2'
,
'#E6CEF2'
]);
const
greens
=
[
BasicGreen
,
DarkGreen
,
SemiDarkGreen
,
LightGreen
,
SuperLightGreen
];
const
yellows
=
[
BasicYellow
,
DarkYellow
,
SemiDarkYellow
,
LightYellow
,
SuperLightYellow
];
const
reds
=
[
BasicRed
,
DarkRed
,
SemiDarkRed
,
LightRed
,
SuperLightRed
];
const
blues
=
[
BasicBlue
,
DarkBlue
,
SemiDarkBlue
,
LightBlue
,
SuperLightBlue
];
const
oranges
=
[
BasicOrange
,
DarkOrange
,
SemiDarkOrange
,
LightOrange
,
SuperLightOrange
];
const
purples
=
[
BasicPurple
,
DarkPurple
,
SemiDarkPurple
,
LightPurple
,
SuperLightPurple
];
ColorsPalete
.
set
(
'green'
,
greens
);
ColorsPalete
.
set
(
'yellow'
,
yellows
);
ColorsPalete
.
set
(
'red'
,
reds
);
ColorsPalete
.
set
(
'blue'
,
blues
);
ColorsPalete
.
set
(
'orange'
,
oranges
);
ColorsPalete
.
set
(
'purple'
,
purples
);
export
const
getColorDefinition
=
(
hex
:
string
):
ColorDefinition
|
undefined
=>
{
return
flatten
(
Array
.
from
(
ColorsPalete
.
values
())).
filter
(
definition
=>
some
(
values
(
definition
.
variants
),
color
=>
color
===
hex
)
)[
0
];
};
export
const
getColorName
=
(
hex
:
string
):
Color
|
undefined
=>
{
const
definition
=
getColorDefinition
(
hex
);
return
definition
?
definition
.
name
:
undefined
;
};
yarn.lock
View file @
ac378790
...
...
@@ -1673,7 +1673,7 @@
resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-1.10.35.tgz#4e5c2b1e5b3bf0b863efb8c5e70081f52e6c9518"
integrity sha512-SVtqEcudm7yjkTwoRA1gC6CNMhGDdMx4Pg8BPdiqI7bXXdCn1BPmtxgeWYQOgDxrq53/5YTlhq5ULxBEAlWIBg==
"@types/lodash@
4.14.119", "@types/lodash@
^4.14.119":
"@types/lodash@^4.14.119":
version "4.14.119"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.119.tgz#be847e5f4bc3e35e46d041c394ead8b603ad8b39"
integrity sha512-Z3TNyBL8Vd/M9D9Ms2S3LmFq2sSMzahodD6rCS9V2N44HUMINb75jNkSuwAx7eo2ufqTdfOdtGQpNbieUjPQmw==
...
...
@@ -1735,7 +1735,7 @@
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@^16.7.6":
"@types/react@*", "@types/react@
16.7.6", "@types/react@
^16.7.6":
version "16.7.6"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.7.6.tgz#80e4bab0d0731ad3ae51f320c4b08bdca5f03040"
integrity sha512-QBUfzftr/8eg/q3ZRgf/GaDP6rTYc7ZNem+g4oZM38C9vXyV8AWRWaTQuW5yCoZTsfHrN7b3DeEiUnqH9SrnpA==
...
...
@@ -4429,7 +4429,7 @@ caniuse-api@^1.5.2:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
caniuse-db@
1.0.30000772, caniuse-db@
^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
version "1.0.30000772"
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000772.tgz#51aae891768286eade4a3d8319ea76d6a01b512b"
integrity sha1-UarokXaChureSj2DGep21qAbUSs=
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment